[英]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]
>>> 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.