Python 迭代器、iterable和迭代到底是什么?
Python中“iterable”、“iterator”和“iteration”最基本的定义是什么 我读过多个定义,但我无法确定确切的含义,因为它仍然无法理解Python 迭代器、iterable和迭代到底是什么?,python,iterator,iteration,terminology,iterable,Python,Iterator,Iteration,Terminology,Iterable,Python中“iterable”、“iterator”和“iteration”最基本的定义是什么 我读过多个定义,但我无法确定确切的含义,因为它仍然无法理解 有人能帮我解释一下外行术语中的3个定义吗?iterable是一个对象,它有一个\uuu iter\uuuu()方法。它可能会重复多次,例如list()s和tuple()s 迭代器是进行迭代的对象。它由\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
有人能帮我解释一下外行术语中的3个定义吗?iterable是一个对象,它有一个
\uuu iter\uuuu()
方法。它可能会重复多次,例如list()
s和tuple()
s
迭代器是进行迭代的对象。它由\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
迭代是调用thisnext()
resp的过程<代码>\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
例如:
>>> 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
>a=[1,2,3]#iterable
>>>b1=iter(a)#迭代器1
>>>b2=iter(a)#迭代器2,独立于b1
>>>下一页(b1)
1.
>>>下一页(b1)
2.
>>>下一步(b2)#重新开始,因为这是对b2的第一次调用
1.
>>>下一页(b1)
3.
>>>下一页(b1)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
停止迭代
>>>b1=iter(a)#新的,重新开始
>>>下一页(b1)
1.
我不认为您可以获得比的简单得多的功能,但是我将尝试:
- Iterable是可以迭代的东西。在实践中,它通常意味着一个序列,例如有一个开始和一个结束的东西,以及通过某种方式遍历其中所有项目
- 您可以将迭代器看作一个辅助伪方法(或伪属性),它给出(或保存)iterable中的下一个(或第一个)项。(实际上,它只是一个定义方法
next()
)的对象)
- 迭代最好的解释可能是《韦氏大词典》:
b:计算机指令序列的重复
次数或直到满足条件-比较递归
迭代是一个通用术语,用于一个接一个地获取某物的每一项。任何时候使用循环(显式或隐式)遍历一组项,这就是迭代
在Python中,iterable和iterator具有特定的含义
iterable是一个对象,它有一个\uuuuuuuuuuuuuuuuuuuuuu
方法,该方法返回一个迭代器,或者定义一个\uuuuuuuu getitem\uuuuuuuuuuuuuuuu
方法,该方法可以从零开始获取顺序索引(并在索引不再有效时引发一个索引器)。因此,iterable是一个对象,您可以从中获得迭代器
迭代器是具有next
(Python 2)或\uuuuuuuuuuuuuuuuuuuuuuuuuuuu
(Python 3)方法的对象
无论何时在Python中使用for
循环、或映射、或列表理解等,都会自动调用next
方法从迭代器中获取每个项,从而完成迭代的过程
一个开始学习的好地方是和。了解基本知识后,请尝试。以下是我在教授Python课程时使用的解释:
一个重要的例子是:
- 可以循环的任何内容(即,可以循环字符串或文件)或
- 可以出现在for循环右侧的任何内容:
对于iterable:…
中的x,或
- 您可以使用
iter()
调用任何将返回迭代器的内容:iter(obj)
或
- 一个对象,定义返回新迭代器的,
或者它可能有一个适合索引查找的
\uuu getitem\uu
方法
迭代器是一个对象:
- 具有在迭代过程中记住其所在位置的状态
- 使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法:
- 返回迭代中的下一个值
- 将状态更新为指向下一个值
- 通过提升
StopIteration
- 也就是说,self-iterable
(这意味着它有一个返回self
的方法)
注:
- Python 3中的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
- 内置函数
next()
对传递给它的对象调用该方法
例如:
>>> s = 'cat' # s is an ITERABLE
# s is a str object that is immutable
# s has no state
# s has a __getitem__() method
>>> t = iter(s) # t is an ITERATOR
# t has state (it starts by pointing at the "c"
# t has a next() method and an __iter__() method
>>> next(t) # the next() function returns the next value and advances the state
'c'
>>> next(t) # the next() function returns the next value and advances
'a'
>>> next(t) # the next() function returns the next value and advances
't'
>>> next(t) # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration
>>> iter(t) is t # the iterator is self-iterable
上面的答案很好,但正如我所看到的,对于像我这样的人来说,不要过分强调区别
此外,人们倾向于“过于Pythonic”,将“X是一个具有\uuu foo\uuu()
方法的对象”这样的定义放在前面。这样的定义是正确的——它们基于duck类型哲学,但是当试图以简单的方式理解概念时,对方法的关注往往介于两者之间
所以我添加了我的版本
在自然语言中
- 迭代是在一行元素中一次获取一个元素的过程
在Python中
- iterable是一个对象,是iterable,简而言之,意思是
它可以在迭代中使用,例如与
for
循环一起使用。怎么用?通过使用迭代器。
我将在下面解释
- 。。。而迭代器是一个定义如何实际执行
迭代——特别是下一个元素是什么。这就是为什么它一定有
next()
方法
迭代器本身也是可迭代的,区别在于它们的\uuuu iter\uuuu()
方法返回相同的对象(self
),而不管其项是否已被先前对next()
的调用使用
那么,当Python解释器在obj:
语句中看到x的时,它会怎么想呢
L
class IterableExample(object):
def __iter__(self):
return self
def next(self):
pass
class Iterator(object):
def next(self):
pass
class Iterable(object):
def __iter__(self):
return Iterator()
class SmartIterableExample(object):
def create_iterator(self):
# An amazingly powerful yet simple way to create arbitrary
# iterator, utilizing object state (or not, if you are fan
# of functional), magic and nuclear waste--no kittens hurt.
pass # don't forget to add the next() method
def __iter__(self):
return self.create_iterator()
>>> X = [1,2,3,4,5]
>>> next(X)
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
next(X)
TypeError: 'list' object is not an iterator
>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>
iterable = [1, 2]
iterator = iter(iterable)
print(iterator.__next__())
print(iterator.__next__())
x=[1,2,3,4]
y=iter(x)
y=[1,2,3,4]
>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration
sequence
+
|
v
def __getitem__(self, index: int):
+ ...
| raise IndexError
|
|
| def __iter__(self):
| + ...
| | return <iterator>
| |
| |
+--> or <-----+ def __next__(self):
+ | + ...
| | | raise StopIteration
v | |
iterable | |
+ | |
| | v
| +----> and +-------> iterator
| ^
v |
iter(<iterable>) +----------------------+
|
def generator(): |
+ yield 1 |
| generator_expression +-+
| |
+-> generator() +-> generator_iterator +-+
class Iterable1:
def __iter__(self):
# a method (which is a function defined inside a class body)
# calling iter() converts iterable (tuple) to iterator
return iter((1,2,3))
class Iterable2:
def __iter__(self):
# a generator
for i in (1, 2, 3):
yield i
class Iterable3:
def __iter__(self):
# with PEP 380 syntax
yield from (1, 2, 3)
# passes
assert list(Iterable1()) == list(Iterable2()) == list(Iterable3()) == [1, 2, 3]
class MyIterable:
def __init__(self):
self.n = 0
def __getitem__(self, index: int):
return (1, 2, 3)[index]
def __next__(self):
n = self.n = self.n + 1
if n > 3:
raise StopIteration
return n
# if you can iter it without raising a TypeError, then it's an iterable.
iter(MyIterable())
# but obviously `MyIterable()` is not an iterator since it does not have
# an `__iter__` method.
from collections.abc import Iterator
assert isinstance(MyIterable(), Iterator) # AssertionError
>>> 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
In[2]: def my_generator():
...: yield 100
...: yield 200
In[3]: my_generator
Out[3]: <function __main__.my_generator()>
In[4]: type(my_generator)
Out[4]: function
In[5]: my_iterator = my_generator()
In[6]: my_iterator
Out[6]: <generator object my_generator at 0x00000000053EAE48>
In[7]: type(my_iterator)
Out[7]: generator
In[8]: my_gen_expression = (2 * i for i in (10, 20))
In[9]: my_gen_expression
Out[9]: <generator object <genexpr> at 0x000000000542C048>
In[10]: type(my_gen_expression)
Out[10]: generator
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
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
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
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
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
if(self.power<=self.max):
result = 2**self.power
self.power +=1
return result
else:
raise StopIteration
ls = ['hello','bye']
print(dir(ls))
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']