如何在 Python 中创建自己的 zip() 函数

问题描述 投票:0回答:7

作为个人练习,我尝试创建自己的小 zip() 函数,该函数接受两个列表并将项目放入元组列表中。换句话说,如果这些是我的清单:

fr = [6,5,4]
tr = [7,8,9]

我希望这样:

[(6,7), (5,8), (4,9)]

这是我的代码:

def zippy(x, y):
    zipper = []
    for i in x :
        for g in y:
            t = (i,g)
        zipper.append(t)

我得到的是:

[(6, 9), (5, 9), (4, 9)]
, 但是当我在函数内部定义列表时,它会按预期工作。任何帮助表示赞赏。

python list iteration
7个回答
3
投票

使用索引访问相同索引的项:

def zippy(x, y):
    zipper = []
    for i in range(len(x)):
        zipper.append((x[i], y[i]))
    return zipper

使用列表理解

def zippy(x, y):
    return [(x[i], y[i]) for i in range(len(x))]

>>> fr = [6,5,4]
>>> tr = [7,8,9]
>>> zippy(fr, tr)
[(6, 7), (5, 8), (4, 9)]

3
投票

请考虑,如果您有两个不同长度的列表,您的压缩应该在最短序列结束时停止。以下是如何操作的示例:

def zippy(x, y):
    iter1 = iter(x)
    iter2 = iter(y)
    while True:
        try:
            yield next(iter1), next(iter2)
        except StopIteration:
            return

def zippy(x, y):
    iter1 = iter(x)
    iter2 = iter(y)
    for _ in range(min(len(x), len(y))):
        yield next(iter1), next(iter2)

另请注意,标准 zip 函数返回(生成器)而不是数据列表!这意味着如果您需要从结果中获取数据,您必须将 zip 结果转换为列表:

result = zippy(fr, tr)
print(list(result))

或者对其调用迭代器

next(result)

2
投票

我建议使用

range()
循环遍历数组的每个索引。然后,将它们放入元组中并将它们附加到数组中。

def zippy(x, y):
    zipper = []
    for i in range(len(x)) :
        zipper.append((x[i],y[i]))
    return zipper

有关

range()
的更多信息,请前往此处


1
投票

您需要同时迭代两个数组才能从两个数组中获取相同的索引

 def zippy(x, y):
        zipper = []
        for i,g in zip(x,y):
            t = (i,g)
            zipper.append(t)
        print(zipper)

输出

[(6, 7), (5, 8), (4, 9)]

1
投票
# A zip() is a kind of map()!
def zippy(a, b):
  return map(lambda (i, a): (a, b[i]), enumerate(a))

0
投票

之前的答案都不支持 Python 原生

zip
函数所支持的可变数量的迭代。考虑以下支持它的通用实现。它也不依赖于
map

def zipper(*iterables):
    # Ref: https://stackoverflow.com/a/77297966
    if not iterables:
        return  # Without this the function runs forever.

    iterables = [iter(iterable) for iterable in iterables]
    while True:
        try:
            yield tuple([next(it) for it in iterables])
        except StopIteration:
            return

使用示例:

> zipper(range(11, 15), range(20, 30))
<generator object zipper at 0x7fb6671a6420>

> list(_)
[(11, 20), (12, 21), (13, 22), (14, 23)]

问题中的示例也可以正常工作。


0
投票

假设您想在操作之前确保列表的长度相等,您可以在函数中使用Python的

assert
语句以及列表理解。

def zippy(x,y):
    assert len(x) == len(y), 'Lists must be equal length to each other'

    return [(i,j) for i,j in zip(x,y)]

assert
语句确保参数x和y的长度相等。如果它们不相等,则该函数将不会运行并返回
AssertionError

然后,函数返回从列表推导式创建的列表。列表推导式为列表的每个索引创建一个元组,其中当在列表上调用

zip()
函数时,索引会配对。

如果您不担心像其他解决方案建议的那样使用生成器迭代列表,那么此解决方案将非常有用。

© www.soinside.com 2019 - 2024. All rights reserved.