在两个列表上使用zip()与两个可迭代对象进行比较

时间:2012-08-22 21:23:25

标签: python python-2.7

作为免责声明,我对编程比较陌生,所以请原谅我在编写这个问题时所做的任何简单疏忽。

我正在使用Python 2.7.3并且在这样做时,注意到了一些对我来说不寻常的东西,并且无法通过Google搜索或Python文档找到令人满意的解释。我可以创建一个列表并使用zip()创建一个元组列表,如下所示:

numList = range(4)
print zip(numList, numList)

[(0, 0), (1, 1), (2, 2), (3, 3)]

但是当我在numList上使用iter()函数创建一个可迭代对象并以类似的方式在这个对象上使用zip()时,我得到了一个非常不同的结果:

numList = range(4)
numList = iter(numList)
print zip(numList, numList)

[(0, 1), (2, 3)]

如果有人能够解释这两个程序之间的区别以及导致这种情况发生的幕后情况,我将不胜感激。

2 个答案:

答案 0 :(得分:6)

在第一种情况下,您为zip提供了“两个”列表(实际上是相同的对象,即列表,但是您提供了两个引用),因此它会交替地从每个列表中提取相同的信息,并且“拉链吧。使用该信息消耗它。

在第二种情况下,您创建一个迭代器,可以根据需要生成0到3“动态”的值。

现在,您将此迭代器提供两次zip(再次,对迭代器的相同引用),它从每个迭代器中“拉出”数据。 (即它调用迭代器的next()函数)。

“first”迭代器提供第一个值0,“second”迭代器(实际上只是对同一个迭代器的引用)提供下一个值1,依此类推,直到迭代器在3耗尽。

因此,要记住的主要事情是,在两种情况下,您向zip提供的内容都是对相同对象的两个相同引用。在第一种情况下,列表包含 all 已经交错/压缩的数据(访问/使用数据不会使其不可用)。在第二种情况下,数据正在按需生成,因此生成的序列是交错/压缩的,并且在生成每个值时,它将被消耗,随后不再可用。

我希望这有一定道理(在一张纸上画出更容易:)

答案 1 :(得分:3)

当迭代迭代器时,会从中消耗元素,因此每个数字只出现一次。

当您对同一列表进行两次迭代时,会从中生成两个单独的列表迭代器,并且每个都会生成一次数字,因此总体而言每个数字都会出现两次。

你的第一个程序相当于做

print zip(iter(numList), iter(numList))