可迭代和迭代器

问题描述

with open("weather_data.csv",'r') as data_file:
    data = csv.reader(data_file)
    for x in data:
        print(x)

我的理解是:csv.reader(data_file)一个迭代器,它调用 iter(self) 并返回 _i 作为迭代器。此 _i 每次调用 next() 以进入下一次迭代。但是,我使用 print(help(csv.reader(data_file)) 并发现

 Methods defined here:
 |  
 |  __iter__(self,/)
 |      Implement iter(self).
 |  
 |  __next__(self,/)
 |      Implement next(self).

我的问题是,这里的方法 __next__(self,/)_i 每次调用方法完全相同吗? _i 是否也携带数据?

解决方法

csv.reader 对象是它自己的迭代器。这是单程迭代(即只能运行一次)的常见做法。我们可以通过检查确认这一点。

>>> data
<_csv.reader object at 0x7fe5d4a057b0>
>>> iter(data)
<_csv.reader object at 0x7fe5d4a057b0> # Note: Same as above
>>> id(data)
140625091516336
>>> id(iter(data))
140625091516336 # Note: Same as above
>>> data is iter(data)
True

将此与列表之类的东西进行比较,列表是可迭代的,但本身不是迭代器。

>>> lst = [1,2,3]
>>> lst
[1,3]
>>> iter(lst)
<list_iterator object at 0x7fe5d59747f0> # Note: NOT the same as before
>>> lst is iter(lst)
False

这允许我们通过多次调用 iter(lst) 对列表进行多次迭代,因为每次调用都会给我们一个新的迭代器。但是您的 csv.reader 对象是单次传递的,因此我们只有一个迭代器。

在 Python 中,每个迭代器都是一个迭代器,但并非每个迭代器都是一个迭代器。来自the glossary

迭代器必须有一个返回迭代器对象本身的 __iter__() 方法,因此每个迭代器也是可迭代的,并且可以在大多数接受其他迭代器的地方使用。