xrange 作为迭代器和分块
xrange as an iterator and chunking
片段
xi = xrange(10)
zip(xi,xi)
和
xi = iter(range(10))
zip(xi,xi)
表现不同。我希望得到
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]
也在第一个片段中,但是 returns
[(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)]'
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)]
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])
。
我认为您对 xrange
类型有误解。基于关于 xrange
类型的 pythons 文档:
The xrange type is an immutable sequence which is commonly used for looping. The advantage of the xrange type is that an xrange object will always take the same amount of memory, no matter the size of the range it represents. There are no consistent performance advantages.
以及以下重要部分:
XRange objects have very little behavior: they only support indexing, iteration, and the len() function.
xrange
对象不是迭代器,它只是一个不透明的序列类型,它产生与相应列表相同的值,实际上并没有同时存储它们,因为如果不遍历就无法访问迭代器元素它的前面的项目并且它不支持索引或 len()
function.and 等操作,当你遍历迭代器时你不能返回!
所以在第二个代码中,zip
函数在每次迭代时消耗每个项目,它只能访问下一个项目。
片段
xi = xrange(10)
zip(xi,xi)
和
xi = iter(range(10))
zip(xi,xi)
表现不同。我希望得到
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]
也在第一个片段中,但是 returns
[(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)]'
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)]
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])
。
我认为您对 xrange
类型有误解。基于关于 xrange
类型的 pythons 文档:
The xrange type is an immutable sequence which is commonly used for looping. The advantage of the xrange type is that an xrange object will always take the same amount of memory, no matter the size of the range it represents. There are no consistent performance advantages.
以及以下重要部分:
XRange objects have very little behavior: they only support indexing, iteration, and the len() function.
xrange
对象不是迭代器,它只是一个不透明的序列类型,它产生与相应列表相同的值,实际上并没有同时存储它们,因为如果不遍历就无法访问迭代器元素它的前面的项目并且它不支持索引或 len()
function.and 等操作,当你遍历迭代器时你不能返回!
所以在第二个代码中,zip
函数在每次迭代时消耗每个项目,它只能访问下一个项目。