【问题标题】:xrange as an iterator and chunkingxrange 作为迭代器和分块
【发布时间】:2015-09-13 02:14:39
【问题描述】:

sn-ps

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

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

表现不同。我希望得到

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

在第一个 sn-p 中也是如此,但它返回

[(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)]'

【问题讨论】:

  • "似乎隐式容器正在被静默复制。" - 你的意思是?为什么需要一个副本来产生观察到的行为?你对xi = [1, 2, 3, 4]; zip(xi, xi) 有什么期望?
  • (此外,尽管人们一遍又一遍地称它为生成器,但 xrange 并不是生成器。xrange 是不可变的序列。)
  • @user2357112 你的第二条评论解释了它。我希望 xrange 作为生成器是“有状态的”,而不是不可变的。

标签: python range xrange


【解决方案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】:

    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)]
    

    【讨论】:

      【解决方案3】:

      我认为您对xrange 类型有误解。基于关于xrange类型的pythons文档:

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

      以及以下重要部分:

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

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

      所以在第二个代码中,zip 函数在每次迭代中消耗每个项目,它只能访问下一个项目。

      【讨论】:

      • 确实如此。我一直认为 xrange 与生成器具有相同的语义。很高兴得到纠正。
      • @srean 实际上它大约 90% 像 range 但例如对于一个迭代器,我们可以说它的 10% 像一个范围 :)(仅作为示例)
      猜你喜欢
      • 2018-02-06
      • 1970-01-01
      • 2011-01-26
      • 2020-05-18
      • 2011-06-17
      • 2020-06-05
      • 2015-05-20
      • 2016-02-28
      • 1970-01-01
      相关资源
      最近更新 更多