Python中的list和iterator有什么区别?

Abh*_*hra 14 python iterator list python-2.7 python-3.x

我正在读" Think Python:如何像计算机科学家一样思考"这本书,它说在Python 3.x中,dict([list of tuples])返回一个iterator而不是一个list(如Python 2.7中的情况).

这本书没有进一步解释,这让我感到困惑.特别是,我想知道:

  1. 迭代器和列表是如何不同的,以及

  2. 在列表上返回迭代器有什么好处?

Zer*_*eus 24

首先,你的书是错的(或者你误解了它):

>>> dict([(1, 2), (3, 4), (5, 6)])
{1: 2, 3: 4, 5: 6}
Run Code Online (Sandbox Code Playgroud)

如您所见,在Python 2.x和3.x中都返回一个字典.dict([list of tuples])

列表和迭代器之间的根本区别在于列表包含特定顺序的多个对象 - 例如,您可以从中间的某个位置拉出其中一个对象:

>>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> my_list
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> my_list[3]
'd'
Run Code Online (Sandbox Code Playgroud)

...而迭代器会按特定顺序生成许多对象,通常会根据请求动态创建它们:

>>> my_iter = iter(range(1000000000000))
>>> my_iter
<range_iterator object at 0x7fa291c22600>
>>> next(my_iter)
0
>>> next(my_iter)
1
>>> next(my_iter)
2
Run Code Online (Sandbox Code Playgroud)

我在next()这里用于演示目的; 在实际代码中,使用for循环遍历迭代器更常见:

for x in my_iter:
    # do something with x
Run Code Online (Sandbox Code Playgroud)

请注意权衡:一个万亿整数的列表将使用比大多数机器更多的内存,这使得迭代器更加高效......代价是无法在中间的某个位置请求对象:

>>> my_iter[37104]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'range_iterator' object is not subscriptable
Run Code Online (Sandbox Code Playgroud)


che*_*ner 12

列表是包含一系列值的数据结构.迭代器是一个对象,它提供一个接口,通过该next函数一次检索一个值.

可迭代对象是提供__iter__方法的对象,在将迭代iter函数传递给函数时调用该方法.您通常不需要明确地这样做; for例如,一个循环是隐含的.像一个循环

for x in [1,2,3]:
    print x
Run Code Online (Sandbox Code Playgroud)

自动调用list__iter__方法.你可以明确地这样做

for x in iter([1,2,3]):
    print x
Run Code Online (Sandbox Code Playgroud)

甚至更明确地说

for x in [1,2,3].__iter__():
    print x
Run Code Online (Sandbox Code Playgroud)

查看区别的一种方法是从单个列表创建两个迭代器.

l = [1, 2, 3, 4, 5]
i1 = iter(l)
i2 = iter(l)
print next(i1)   # 1
print next(i1)   # 2
print next(i2)   # 1 again; i2 is separate from i1
print l          # [1, 2, 3, 4, 5]; l is unaffected by i1 or i2
Run Code Online (Sandbox Code Playgroud)

  • `iter` 返回一个迭代器。生成器只是迭代器的一种。查看`type(iter([1,2,3]))`。 (2认同)
  • 这是不正确的。任何提供“__next__”(因此可以传递给“next”)的东西都是迭代器。可迭代对象是提供“__iter__”的东西(因此可以传递给“iter”)。生成器只是一种迭代器,由使用“yield”的可调用对象创建,但并非所有迭代器都是使用“yield”创建的。 (2认同)

Rob*_*vey 5

迭代器是您可以使用遍历列表或其他一组对象/值的机制for。列表实现了一个迭代器。但是,您也可以实现返回数字序列,随机字符串等的迭代器。

当您返回一个迭代器时,您只是在返回迭代对象。接收代码对底层容器或生成器算法一无所知。

迭代器是惰性的;它们仅在要求时返回序列或列表中的下一个元素。因此,您可以使用它们实现无限序列。

进一步阅读
迭代器类型
for语句


Ton*_* 66 5

这里的关键定义是:

  • List :完全存储在内存中,并且它也是一个迭代器 - 即您可以从一个元素转到下一个元素。
  • Iterable :任何实现迭代器协议的对象 - 即允许您从一个元素转到下一个元素。它可以使用存储在内存中的数据,也可以是文件,或者可以计算每个步骤。

很多东西都是可迭代的,但不是列表,所有列表都是可迭代的