簡體   English   中英

為什么xrange能夠在Python中重新開始?

[英]why is xrange able to go back to beginning in Python?

我從大多數pythonic方法中遇到了這個代碼, 用於計算可迭代的匹配元素

r = xrange(1, 10)
print sum(1 for v in r if v % 2 == 0) # 4
print sum(1 for v in r if v % 3 == 0) # 3

r迭代一次。 然后它再次迭代。 我想如果一個迭代器被消耗掉,那么它就結束了,它不應該再次迭代。

生成器表達式只能迭代一次:

r = (7 * i for i in xrange(1, 10))
print sum(1 for v in r if v % 2 == 0) # 4
print sum(1 for v in r if v % 3 == 0) # 0

枚舉(L):

r = enumerate(mylist)

和文件對象:

f = open(myfilename, 'r')

為什么xrange表現不同?

因為xrange不返回生成器。 它返回一個xrange對象

>>> type(xrange(10))
<type 'xrange'>

除了重復迭代之外, xrange對象還支持生成器不需要的其他東西 - 比如索引:

>>> xrange(10)[5]
5

他們也有一個長度:

>>> len(xrange(10))
10

他們可以逆轉:

>>> list(reversed(xrange(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

簡而言之, xrange對象實現了完整的序列 接口

>>> import collections
>>> isinstance(xrange(10), collections.Sequence)
True

他們只是在不占用大量內存的情況下完成它。

還要注意,在Python 3, range由返回的對象range具有完全相同的屬性。

因為通過調用xrange()生成的xrange對象指定__iter__ ,每次迭代時都會提供自身的唯一版本(實際上是一個單獨的rangeiterator對象)。

>>> x = xrange(3)
>>> type(x)
<type 'xrange'>
>>> i = x.__iter__()
>>> type(i)
<type 'rangeiterator'>

如果你所知道的是它是一個迭代器,那么一般來說你必須假設你只能迭代一次。 這並不意味着每個迭代器只能被消耗一次,只是每個迭代器至少可以消耗一次。 明顯的例子是列表和其他序列支持此接口。

正如senderle和Amber所解釋的那樣,通過調用xrange獲得的特定迭代器碰巧被實現,以便您可以多次迭代它們。

通用迭代器的想法允許迭代器在迭代后可能會耗盡。 這是因為許多迭代器(例如生成器,文件遍歷等)難以實現,或者消耗更多內存或運行速度慢得多,如果它們必須支持任意多次遍歷,並且通常這種功能甚至不會用過的。 因此,如果迭代器必須支持任意多次遍歷,那么這些東西可能不會是迭代器。

長話短說,如果你正在編寫上的任意未知的迭代器操作的代碼,你認為它只能使用一次遍歷,如果有人給你支持比你需要的功能更像一個對象也沒關系。 如果您知道有關迭代器的一些其他信息(例如它也是一個序列,或者甚至是它是一個xrange對象),那么您可以編寫代碼以便在需要時使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM