在Python 3中打印zip()函数的结果会显示"zip object at <address>"。

81

我知道如何在Python 3中使用zip()函数。我的问题与以下内容有关,这使我感到相当奇怪:

我定义了两个列表:

lis1 = [0, 1, 2, 3]
lis2 = [4, 5, 6, 7]

我在以下方式中使用zip()

1. test1 = zip( lis1, lis2)

2. test2 = list(zip(lis1, lis2))

当我在解释器中输入 test1 时,会得到以下结果:

"zip object at 0x1007a06c8"

所以,我在解释器中键入list(test1)并获得预期结果,但是当我再次键入list(test1)时,我会得到一个空列表。

我发现奇怪的是,无论我在解释器中键入多少次test2,我总是得到预期的结果,而不是空列表。


2
Python 3 中更简洁的写法:test2 = [*zip(lis1, lis2)] - Friedrich -- Слава Україні
我重新打开这个问题,因为它不仅涉及到迭代器在Python中的工作方式的一般问题;更具体地说,它涉及到了zip在3.x版本中生成迭代器而不是列表(就像在2.x版本中那样)的事实。我无法找到一个更好的版本的问题,只关注后者部分。 - Karl Knechtel
@KarlKnechtel:同意,我也找不到一个,但现在有几篇帖子指向这个。 - Martijn Pieters
@MartijnPieters,我找到了它:TypeError: 'zip' object is not subscriptable。它需要一些编辑才能成为一个有用的规范,但其他东西可能更适合关闭到那里,而这个问题可以同时关闭(并且不是一个好的目标)。 - Karl Knechtel
2个回答

115

与Python 2不同的是,Python 3中的zip函数返回一个迭代器。迭代器只能被耗尽一次(通过将它们转换为列表等方式)。其目的是通过仅在需要时生成迭代器的元素来节省内存,而不是一次性将所有元素放入内存中。如果您想重复使用已压缩的对象,请像第二个示例中那样创建一个列表,然后通过类似于以下方式复制该列表:

 test2 = list(zip(lis1,lis2))
 zipped_list = test2[:]
 zipped_list_2 = list(test2)

这个伟大解释中最重要的词之一是“once”。即使测试压缩对象的长度 len(list(zipped)),它也会被耗尽。 - DaveL17

31
Python 3 的 zip() 函数返回一个迭代器。因此,当您打印 test1 时,会得到 - <zip object at 0x1007a06c8>。根据文档说明 -

创建一个迭代器,该迭代器从每个可迭代对象中聚合元素。

但是,一旦您执行了 - list(test1) - 您就已经耗尽了迭代器。因此,在那之后,无论何时执行 list(test1) 都只会导致空列表。

对于 test2,您已经创建了列表,因此它始终是该列表。


这种行为难道不适用于生成器,而不是迭代器吗? - Jeremy Fisher
为什么迭代器不适用?请查看 - https://dev59.com/WHE85IYBdhLWcg3wbTD2 - 每个生成器都是一个迭代器。迭代器也可能会被耗尽,同样地,有些生成器永远不会被耗尽。 - Anand S Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接