xrange作为迭代器和分块

时间:2015-06-26 07:51:22

标签: python range xrange

片段

 xi = xrange(10)
 zip(xi,xi)

 xi = iter(range(10))
 zip(xi,xi)

表现不同。我希望得到

  [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]

也在第一个代码段中,但它返回

[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]

代替。看起来隐式容器正在被静默复制。谁能解释一下这里发生了什么?选择这种语义背后的推理。

>>> sys.version
'2.7.9 (default, Dec 10 2014, 12:28:03) [MSC v.1500 64 bit (AMD64)]'

3 个答案:

答案 0 :(得分:1)

xrange对象不是迭代器,而是可迭代对象。通过将它提供给iter函数,您可以获得迭代器。 zip函数在其所有参数上隐式调用iter,因此它在xrange对象上生成两个并行迭代器。在第二个示例中,您手动调用iter,因此您将苹果与橙子进行比较。要获得xrange所需的效果,您应该

In [5]: it = iter(xrange(10))
   ...: zip(it, it)
Out[5]: [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]

答案 1 :(得分:1)

xrange不是任何迭代器。人们一直称它为发电机,但事实并非如此; xrange是一个不可变的序列,就像一个元组:

>>> x = xrange(5)
>>> x[2]
2
>>> for i in x:
...     print i
...
0
1
2
3
4
>>> for i in x:
...     print i
...
0
1
2
3
4

与任何其他序列类型一样,每次从xrange请求迭代器时,都会得到一个新的独立迭代器。因此,当您自己压缩xrange(10)时,您会得到与您自己压缩[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]相同的输出,而不是您自己压缩iter([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

答案 2 :(得分:1)

我认为您对xrange类型缺乏了解。基于pythons关于xrange类型的文档:

  

xrange类型是一个不可变的序列,通常用于循环。 xrange类型的优点是xrange对象总是占用相同数量的内存,无论它所代表的范围大小。没有一致的性能优势。

以下重要部分:

  

XRange对象的行为很少:它们只支持索引,迭代和 len()函数。

xrange对象不是迭代器,它只是一个不透明的序列类型,它产生与相应列表相同的值,而不是实际同时存储它们,因为你不能访问迭代器元素而不遍历它的前面项目,它不支持索引或len()函数等操作。当你遍历迭代器时,你不能回去!

因此,在第二个代码中,zip函数在每次迭代时使用每个项目,它只能访问下一个项目。

相关问题