【问题标题】:What do you call the item of list when used as an iterator in a for loop?在 for 循环中用作迭代器时,您将列表项称为什么?
【发布时间】:2017-01-23 02:40:55
【问题描述】:

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

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

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

【问题讨论】:

  • 我看到它被称为“项目”。变量名通常取决于迭代的内容(例如 for line in filefor row in rows 等)
  • @linusg 我怀疑一本基本的编程书籍是否指定了我们所说的这些元素。仅举一个例子,this primer on for loops 没有命名它们。
  • @GreenAsJade - 同意,但了解for 循环在 Python 中的工作方式将是一个好的开始。以后,他可以学习所有花哨的名字,比如迭代器等等。
  • 感谢大家的帮助。 @ linusg 我相信我确实了解for 循环的工作原理,但我试图向班上的其他学生解释它的用途,因此能够给它起一个不会混淆它的独特名称非常有用与其他概念。
  • “循环变量”是程序员常用的说法,但不知道Python官方有没有术语。请注意,在 Python 中可以有多个循环变量:for n,item in enumerate(a_list)for k,v in a_dict.items()for x,y,z in coords_list 等。

标签: python terminology


【解决方案1】:

你给出的例子是"iterator-based for-loop"

n 被称为loop variable

list所扮演的角色比较麻烦。

确实,在与@juanpa.arrivillaga 进行了一次有趣的对话后,我得出的结论是,对于该句法元素,根本没有“明确正确的正式名称”,也没有常用名称。

话虽如此,我确实认为如果您在句子中将它称为“循环迭代器”,每个人都会知道您的意思。

这样做时,您会冒着让自己或其他人混淆的风险,因为该位置的句法元素实际上不是迭代器,它是一个集合或(松散地,但来自参考文章中的定义) “某种可迭代的”。

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

【讨论】:

  • 注意:我认为您可以将列表称为“迭代器”,但“循环迭代器”更清晰,因为“迭代器”是一个重载的术语。
  • 列表不是迭代器。
  • 正如对您的答案的评论中所讨论的,该列表不是python iterator,但它是loop iterator 这个iterator-based for-loop 构造中的@。
【解决方案2】:

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

它是一个可迭代的,因为它实现了一个__iter__ 方法,该方法返回一个迭代器:

Python Glossary一个可迭代是:

一个能够一次返回其成员的对象。示例 可迭代对象包括所有序列类型(例如 list、str 和 tuple) 以及一些非序列类型,如字典、文件对象和 您使用__iter__()__getitem__() 方法定义的任何类。 Iterables 可用于 for 循环和许多其他地方 需要序列(zip(),map(),...)。 当一个可迭代对象是 作为参数传递给内置函数iter(),它返回一个 对象的迭代器。此迭代器适用于一次通过 一组值。使用可迭代对象时,通常不需要 调用 iter() 或自己处理迭代器对象。 for 语句 自动为您执行此操作,创建一个临时的未命名变量 在循环期间保持迭代器。

所以,观察:

>>> 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迭代器是:

表示数据流的对象。反复调用 迭代器的__next__() 方法(或将其传递给内置函数 next()) 返回流中的连续项目。当没有更多数据时 而是引发了一个 StopIteration 异常。在此刻, 迭代器对象已用尽并且对其的任何进一步调用 __next__() 方法只是再次引发 StopIteration。 迭代器必须有一个返回迭代器对象的__iter__() 方法 本身,所以每个迭代器也是可迭代的,并且可以在大多数情况下使用 接受其他迭代的地方。一个值得注意的例外是 尝试多次迭代的代码。容器对象 (例如列表)每次传递时都会产生一个新的迭代器 到 iter() 函数或在 for 循环中使用它。尝试这个 迭代器将只返回使用的相同耗尽的迭代器对象 在之前的迭代过程中,使它看起来像一个空的 容器。

我已经用上面的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

【讨论】:

  • 我认为您混淆了不幸重载的术语 iterator 的两种用法。 Python 有一个iterator 的正式定义,而且列表确实不是其中之一。但是,在基本分类学术语中,python for 循环是 iterator-based for-loop 。此构造的组件是loop variable 和(循环)iterator。不幸的是,这些不同的定义/用法存在......但它们确实存在。后一个服务于 OP 的目的。您没有在答案中提供替代方案。
  • @GreenAsJade 很抱歉,但我仍然不同意。来自您自己的链接:“它通常以使用隐式或显式迭代器为特征,其中循环变量采用序列或其他数据集合中的每个值。”在 Python for-each 构造中,循环迭代器是隐式的。我们约定的循环变量,列表就是序列或者其他数据集合。
  • “通常”。这允许其他情况。在 Python 中,我们还可以使用 list。我同意它作为术语冲突并不理想,但据我所知,问题的答案。我不知道此构造的任何其他分类法。
  • @GreenAsJade 另外,如果您点击iterator article 的链接,它会显示:“在计算机编程中,迭代器是一种对象,它使程序员能够遍历容器,特别是列表。”迭代器不是容器,它是一个可以遍历的对象。
  • 再一次:我并不是说这个构造中的列表是python iterator。显然不是。但是,它在iterator-based for-loop 构造中扮演iterator 的角色。这是它正在播放的角色名称。 Python 恰好支持在该角色中放置一个列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
  • 2017-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多