Python中的“iterable”、“iterator”和“iteration”是什么?它们是如何定义的?
当前回答
Iterable:-可迭代的东西是可迭代的;比如序列,比如列表,字符串等等。 它也有__getitem__方法或__iter__方法。现在如果我们对该对象使用iter()函数,我们将得到一个迭代器。
迭代器:-当我们从iter()函数获得迭代器对象;我们调用__next__()方法(在python3中)或简单地调用next()(在python2中)来逐个获取元素。该类或该类的实例称为迭代器。
从文档:
迭代器的使用遍及并统一了Python。在后台,for语句在容器对象上调用iter()。该函数返回一个迭代器对象,该对象定义了__next__()方法,该方法每次访问容器中的一个元素。当没有更多的元素时,__next__()会引发一个StopIteration异常,告诉for循环终止。你可以使用next()内置函数调用__next__()方法;这个例子展示了它是如何工作的:
>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
next(it)
StopIteration
一个类的前:-
class Reverse:
"""Iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
... print(char)
...
m
a
p
s
其他回答
iterable是一个具有__iter__()方法的对象。它可以迭代多次,比如list()和tuple()。
迭代器是进行迭代的对象。它由__iter__()方法返回,通过自己的__iter__()方法返回自身,并有一个next()方法(3.x中的__next__())。
迭代是调用next()响应的过程。__next__()直到引发StopIteration。
例子:
>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1
迭代器是实现iter和next方法的对象。如果定义了这些方法,则可以使用for循环或推导式。
class Squares:
def __init__(self, length):
self.length = length
self.i = 0
def __iter__(self):
print('calling __iter__') # this will be called first and only once
return self
def __next__(self):
print('calling __next__') # this will be called for each iteration
if self.i >= self.length:
raise StopIteration
else:
result = self.i ** 2
self.i += 1
return result
迭代器会耗尽。这意味着在你遍历项目之后,你不能重复,你必须创建一个新对象。假设你有一个类,它包含cities属性,你想要遍历。
class Cities:
def __init__(self):
self._cities = ['Brooklyn', 'Manhattan', 'Prag', 'Madrid', 'London']
self._index = 0
def __iter__(self):
return self
def __next__(self):
if self._index >= len(self._cities):
raise StopIteration
else:
item = self._cities[self._index]
self._index += 1
return item
类Cities的实例是一个迭代器。然而,如果你想在城市上重复,你必须创建一个新对象,这是一个昂贵的操作。你可以把这个类分成两个类:一个返回城市,第二个返回一个迭代器,它将城市作为初始参数。
class Cities:
def __init__(self):
self._cities = ['New York', 'Newark', 'Istanbul', 'London']
def __len__(self):
return len(self._cities)
class CityIterator:
def __init__(self, city_obj):
# cities is an instance of Cities
self._city_obj = city_obj
self._index = 0
def __iter__(self):
return self
def __next__(self):
if self._index >= len(self._city_obj):
raise StopIteration
else:
item = self._city_obj._cities[self._index]
self._index += 1
return item
现在如果我们需要创建一个新的迭代器,我们不需要再次创建数据,也就是城市。我们创建了cities对象并将其传递给迭代器。但我们仍在做额外的工作。我们可以通过只创建一个类来实现这一点。
Iterable是一个实现Iterable协议的Python对象。它只需要返回一个迭代器对象的新实例的__iter__()。
class Cities:
def __init__(self):
self._cities = ['New York', 'Newark', 'Istanbul', 'Paris']
def __len__(self):
return len(self._cities)
def __iter__(self):
return self.CityIterator(self)
class CityIterator:
def __init__(self, city_obj):
self._city_obj = city_obj
self._index = 0
def __iter__(self):
return self
def __next__(self):
if self._index >= len(self._city_obj):
raise StopIteration
else:
item = self._city_obj._cities[self._index]
self._index += 1
return item
迭代器有__iter__和__next__,可迭代对象有__iter__,所以我们可以说迭代器也是可迭代对象,但它们是耗尽的可迭代对象。另一方面,迭代对象永远不会耗尽 因为它们总是返回一个新的迭代器,然后用于迭代
你注意到可迭代器代码的主要部分是在迭代器中,而可迭代器本身只不过是一个额外的层,允许我们创建和访问迭代器。
在可迭代对象上迭代
Python有一个内置的函数iter(),它调用__iter__()。当我们遍历一个可迭代对象时,Python调用iter(),它返回一个迭代器,然后它开始使用迭代器的__next__()来遍历数据。
注意,在上面的例子中,Cities创建了一个可迭代对象,但它不是一个序列类型,这意味着我们不能通过索引获得一个城市。为了解决这个问题,我们应该将__get_item__添加到Cities类中。
class Cities:
def __init__(self):
self._cities = ['New York', 'Newark', 'Budapest', 'Newcastle']
def __len__(self):
return len(self._cities)
def __getitem__(self, s): # now a sequence type
return self._cities[s]
def __iter__(self):
return self.CityIterator(self)
class CityIterator:
def __init__(self, city_obj):
self._city_obj = city_obj
self._index = 0
def __iter__(self):
return self
def __next__(self):
if self._index >= len(self._city_obj):
raise StopIteration
else:
item = self._city_obj._cities[self._index]
self._index += 1
return item
我不认为你能得到比文档更简单的东西,但我会尝试:
Iterable是可以被迭代的对象。在实践中,它通常是指一个序列,例如,有开始和结束的东西,以及一些贯穿其中所有项目的方法。 您可以将Iterator视为一个辅助伪方法(或伪属性),它给出(或保存)可迭代对象中的下一个(或第一个)项。(实际上它只是一个定义next()方法的对象) 《韦氏词典》对迭代这个词的定义可能是最好的解释:
B:重复指定的计算机指令序列 次数或直到满足条件-比较递归
Iterable:-可迭代的东西是可迭代的;比如序列,比如列表,字符串等等。 它也有__getitem__方法或__iter__方法。现在如果我们对该对象使用iter()函数,我们将得到一个迭代器。
迭代器:-当我们从iter()函数获得迭代器对象;我们调用__next__()方法(在python3中)或简单地调用next()(在python2中)来逐个获取元素。该类或该类的实例称为迭代器。
从文档:
迭代器的使用遍及并统一了Python。在后台,for语句在容器对象上调用iter()。该函数返回一个迭代器对象,该对象定义了__next__()方法,该方法每次访问容器中的一个元素。当没有更多的元素时,__next__()会引发一个StopIteration异常,告诉for循环终止。你可以使用next()内置函数调用__next__()方法;这个例子展示了它是如何工作的:
>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
next(it)
StopIteration
一个类的前:-
class Reverse:
"""Iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
... print(char)
...
m
a
p
s
对我来说,Python的glossery对这些问题最有帮助,例如对于iterable,它说:
每次能够返回一个成员的对象。可迭代对象的例子包括所有序列类型(如list、str和tuple)和一些非序列类型,如dict、文件对象,以及使用iter()方法或使用实现sequence语义的getitem()方法定义的任何类的对象。
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. See also iterator, sequence, and generator.
推荐文章
- python中的assertEquals和assertEqual
- 如何保持Python打印不添加换行符或空格?
- 为什么Python的无穷散列中有π的数字?
- Python 3.7数据类中的类继承
- 如何在PyTorch中初始化权重?
- 计数唯一的值在一列熊猫数据框架像在Qlik?
- 使用Pandas将列转换为行
- 从matplotlib中的颜色映射中获取单个颜色
- 将Pandas或Numpy Nan替换为None以用于MysqlDB
- 使用pandas对同一列进行多个聚合
- 使用Python解析HTML
- django MultiValueDictKeyError错误,我如何处理它
- 如何在for循环期间修改列表条目?
- 我如何在Django中创建一个鼻涕虫?
- 没有名为'django.core.urlresolvers'的模块