当在 for 循环中用作迭代器时,您如何称呼列表项?

What do you call the item of list when used as an iterator in a for loop?

我不确定您如何在下面的 for 循环中命名 n。它有一个术语吗?

for n in [1,2,3,4,5]:
    print i

而且,我是否正确认为列表本身是 for 循环的 iterator

你举的例子是"iterator-based for-loop"

n 称为 loop variable.

list扮演的角色起名字比较麻烦

事实上,在与@juanpa.arrivillaga 进行了一次有趣的对话后,我得出的结论是,对于该句法元素,根本没有 "clearly correct formal name",也没有常用名称。

话虽这么说,但我确实认为,如果您在句子的上下文中提到它 "the loop iterator",每个人都会明白您的意思。

在这样做时,您冒着让自己或其他人感到困惑的风险,因为该位置的句法元素实际上不是迭代器,它是一个集合或(松散地,但从引用中的定义文章) "iterable of some sort".

我怀疑没有为此命名的一个原因是我们几乎不必在句子中提及它。另一个是可以出现在该位置的元素类型差异很大,因此很难用标签安全地覆盖它们。

虽然 n 被称为 循环变量 列表绝对 不是 迭代器。它是可迭代对象,即 iterable,但它不是 iterator。可迭代对象本身可能是迭代器,但并非总是如此。也就是说,迭代器是可迭代的,但并不是所有的可迭代对象都是迭代器。在 list 的情况下,它只是一个可迭代对象。

它是一个可迭代对象,因为它实现了一个 __iter__ 方法,returns 一个迭代器:

Python Glossary 一个 iterable 是:

An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict, file objects, and objects of any classes you define with an __iter__() or __getitem__() method. Iterables can be used in a for loop and in many other places where a sequence is needed (zip(), map(), ...). When an iterable object is passed as an argument to the built-in function iter(), it returns an iterator for the object. This iterator is good for one pass over the set of values. When using iterables, it is usually not necessary to call iter() or deal with iterator objects yourself. The for statement does that automatically for you, creating a temporary unnamed variable to hold the iterator for the duration of the loop.

所以,观察:

>>> x = [1,2,3]
>>> iterator = iter(x)
>>> type(iterator)
<class 'list_iterator'>
>>> next(iterator)
1
>>> next(iterator)
2
>>> next(iterator)
3
>>> next(iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

理解 Python 中的 for 循环是很有启发性的,例如:

for n in some_iterable:
    # do something

相当于:

iterator = iter(some_iterable)
while True:
    try:
        n = next(iterator)
        # do something
    except StopIteration as e:
        break

通过调用对象的 __iter__ 方法返回的迭代器也实现了 __iter__ 方法(通常返回自身),但它们 实现一个 __next__ 方法。因此,检查某物是否可迭代的一种简单方法是查看它是否实现了 next 方法

>>> next(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'list' object is not an iterator

同样,从 Python Glossary 开始,一个 迭代器 是:

An object representing a stream of data. Repeated calls to the iterator’s __next__() method (or passing it to the built-in function next()) return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its __next__() method just raise StopIteration again. Iterators are required to have an __iter__() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted. One notable exception is code which attempts multiple iteration passes. A container object (such as a list) produces a fresh new iterator each time you pass it to the iter() function or use it in a for loop. Attempting this with an iterator will just return the same exhausted iterator object used in the previous iteration pass, making it appear like an empty container.

我已经用上面的 next 函数说明了迭代器的行为,所以现在我想专注于粗体部分。

基本上,可以使用迭代器代替可迭代对象,因为迭代器始终是可迭代的。但是,迭代器只适用于单次传递。所以,如果我使用非迭代器可迭代对象,比如列表,我可以这样做:

>>> my_list = ['a','b','c']
>>> for c in my_list:
...   print(c)
... 
a
b
c

还有这个:

>>> for c1 in my_list:
...   for c2 in my_list:
...     print(c1,c2)
... 
a a
a b
a c
b a
b b
b c
c a
c b
c c
>>> 

迭代器的行为方式几乎相同,所以我仍然可以这样做:

>>> it = iter(my_list)
>>> for c in it:
...   print(c)
... 
a
b
c
>>> 

但是,迭代器不支持多次迭代(好吧,您可以制作一个支持多次迭代的迭代器,但通常它们不支持):

>>> it = iter(my_list)
>>> for c1 in it:
...   for c2 in it:
...     print(c1,c2)
... 
a b
a c

这是为什么?好吧,回想一下for循环所使用的迭代器协议发生了什么,并考虑以下内容:

>>> my_list = ['a','b','c','d','e','f','g']
>>> iterator = iter(my_list)
>>> iterator_of_iterator = iter(iterator)
>>> next(iterator)
'a'
>>> next(iterator)
'b'
>>> next(iterator_of_iterator)
'c'
>>> next(iterator_of_iterator)
'd'
>>> next(iterator)
'e'
>>> next(iterator_of_iterator)
'f'
>>> next(iterator)
'g'
>>> next(iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> next(iterator_of_iterator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> 

当我在迭代器上使用 iter() 时,它返回了自己!

>>> id(iterator)
139788446566216
>>> id(iterator_of_iterator)
139788446566216