对zip对象的列表执行len会清空zip

14 投票
2 回答
5884 浏览
提问于 2025-04-17 14:23

我在使用zip()这个函数时遇到了一些奇怪的情况。当我对一个zip对象z执行len(list(z))这个操作时,结果是0(我觉得这不对),而且这个操作似乎还把zip对象清空了。有人能帮我理解这是怎么回事吗?

# python3
Python 3.2.3 (default, Sep 30 2012, 16:41:36) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> w = [11, 22, 33, 44, 55, 66]
>>> x = [1, 2, 3, 4]
>>> y = ['a', 'b', 'c']
>>> z = zip(x, y, w)
>>> z
<zip object at 0x7f854f613cb0>
>>> list(z)
[(1, 'a', 11), (2, 'b', 22), (3, 'c', 33)]
>>> len(list(z))
0
>>> list(z)
[]
>>> z
<zip object at 0x7f854f613cb0>
>>> 

谢谢,
阿赫迈德。

2 个回答

3

为了补充之前的回答,有一个叫做 cardinality 的Python库,可以用来获取可迭代对象的大小。

你可以在这里找到它的详细信息:http://cardinality.readthedocs.io/en/latest/

16

在Python 3中,zip是一个生成器。当你使用list(z)时,这个生成器就会被消耗掉。你可以从生成器返回的值中创建一个列表,然后对这个列表进行操作。

l = list(z)
len(l)
# -> 3
l
# -> [(1, 'a', 11), (2, 'b', 22), (3, 'c', 33)]

生成器是个好东西。它们让我们可以写出更节省内存的代码,几乎和处理列表的方式一样。举个例子,来自上面链接的维基:

def double(L):
    return [x*2 for x in L]

可以重写成一个生成器,这样就不需要在内存中再创建一个新的列表:

def double(L):
    for x in L:
        yield x*2

撰写回答