Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么xrange能够回到Python的开头?_Python_Iterator_Xrange - Fatal编程技术网

为什么xrange能够回到Python的开头?

为什么xrange能够回到Python的开头?,python,iterator,xrange,Python,Iterator,Xrange,我在中遇到了此代码 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)项: 还有文件对象: f = open(myfilename, 'r') 为什么xrange的行为会有所不同?

我在中遇到了此代码

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)项:

还有文件对象:

f = open(myfilename, 'r')

为什么xrange的行为会有所不同?

因为通过调用
xrange()
生成的
xrange
对象指定了一个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
对象,该对象在每次迭代时都提供其自身的唯一版本(实际上是一个单独的
rangeiterator
对象)

>>> x = xrange(3)
>>> type(x)
<type 'xrange'>
>>> i = x.__iter__()
>>> type(i)
<type 'rangeiterator'>
>x=xrange(3)
>>>类型(x)
>>>i=x.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
>>>第(i)类

因为
xrange
不返回生成器。它返回一个

它们还有一个长度:

>>> len(xrange(10))
10
它们可以颠倒过来:

>>> list(reversed(xrange(10)))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
简而言之,
xrange
对象实现了完整的:

他们只是在不消耗大量内存的情况下完成


还要注意,在Python 3中,由
range
返回的
range
对象具有所有相同的属性。

如果您所知道的只是某个对象是一个迭代器,那么通常必须假设您只能对它迭代一次。这并不意味着每个迭代器只能使用一次,只是每个迭代器至少可以使用一次。一个明显的例子是列表和其他序列支持此接口

正如senderle和Amber所解释的,您通过调用
xrange
获得的特定迭代器恰好实现为您可以对它们进行多次迭代

一般的迭代器思想允许迭代器在迭代后耗尽。这是因为许多迭代器(如生成器、文件遍历等)如果必须支持任意多个遍历,则很难实现,或者消耗更多内存,或者运行速度慢得多,而且通常甚至不会使用此功能。所以,如果迭代器必须支持任意多个遍历,那么这些东西可能不是迭代器


长话短说,如果您正在编写在任意未知迭代器上运行的代码,那么您假定它只能被遍历一次,并且如果有人向您提供的对象支持的功能超过了您所需的功能,这并不重要。如果您知道有关迭代器的一些附加信息(例如它也是一个序列,甚至与它是一个xrange对象一样多),那么您可以编写代码来利用这些信息。

问得好。这种“可重用”类型的集合类型可能应该添加到Python中,因为有很多集合类型:例如ValuesView。()
>>> type(xrange(10))
<type '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