调用list()清空我的可迭代对象?

Pie*_*ckx 13 python list

a = range(1, 3)
a = iter(a)
list(a)
a = list(a)
Run Code Online (Sandbox Code Playgroud)

a评估为[ ].

a = range(1, 3)
a = iter(a)
a = list(a)
Run Code Online (Sandbox Code Playgroud)

a评估为[1, 2].

第一个结果对我来说意外.这里有什么语义?

dim*_*414 26

问题不在于,list()iter()文献记载的是单一用途iterator.一旦某些东西访问了iterator元素,迭代器就会永久为空.更常用的可迭代类型(通常)可重用,并且不应混淆这两种类型.

请注意,您不需要iter()将a range转换为a list,因为list()将a iterable作为参数:

>>> a = range(1, 3)
>>> list(a)
[1, 2]
>>> list(a)
[1, 2]
Run Code Online (Sandbox Code Playgroud)

并且只有iterator返回的iter()是单次使用:

>>> b = iter(a)
>>> list(b)
[1, 2]
>>> list(b)
[]
>>> list(a)
[1, 2]
Run Code Online (Sandbox Code Playgroud)


Pyn*_*hia 5

让我们来看看会发生什么:

>>> a = range(1, 3)
>>> a is iter(a)
False
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,iter给出一个新的迭代器对象,它a本身并不是

>>>> a = iter(a)
Run Code Online (Sandbox Code Playgroud)

a现在名称对应于不同的迭代器对象iter给我们(就好像iter(a)已经返回自己一样,例如它zip与文件一起发生)

>>> list(a)
[1, 2]
Run Code Online (Sandbox Code Playgroud)

因此,耗尽了迭代器

>>> list(a)
[]
Run Code Online (Sandbox Code Playgroud)

因为迭代器已经被使用(迭代),所以没有给出任何东西

以下是一些您可以尝试完全掌握发生情况的实验:

>>> a = range(1, 3)
>>> a
range(1, 3)
>>> type(a)
<class 'range'>
>>> b = iter(a)
>>> b
<range_iterator object at 0x7f331a6d96c0>
>>> type(b)
<class 'range_iterator'>
>>> a is b
False
>>> list(b)
[1, 2]
>>> list(b)
[]
>>> list(a)
[1, 2]
>>> list(a)
[1, 2]
>>> a
range(1, 3)
>>> next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'range' object is not an iterator
>>> b=iter(a)
>>> next(b)
1
>>> next(b)
2
>>> next(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> a=[1,2,3]
>>> b=[4,5,6]
>>> z=zip(a,b)
>>> iter(z) is z
True
>>> with open('words.txt') as f:
...  iter(f) is f
... 
True
Run Code Online (Sandbox Code Playgroud)

注意:在Python 2上有相当多的函数返回列表而不是迭代器(例如zip)