python 迭代器 iterators

python 迭代器 iterators

https://pymotw.com/3/itertools/index.html

https://docs.python.org/3/library/itertools.html

http://realpython.cn/tutorials/topics/python-iterators/

解释:https://docs.python.org/zh-cn/3/glossary.html#term-iterator

python迭代器解释

python术语对照表:https://docs.python.org/zh-cn/3/glossary.html#term-iterator

iterator – 迭代器

用来表示一连串数据流的对象。重复调用迭代器的 __next__() 方法(或将其传给内置函数 next())将逐个返回流中的项。当没有数据可用时则将引发 StopIteration 异常。到这时迭代器对象中的数据项已耗尽,继续调用其 __next__() 方法只会再次引发 StopIteration 异常。迭代器必须具有 __iter__() 方法用来返回该迭代器对象自身,因此迭代器必定也是可迭代对象,可被用于其他可迭代对象适用的大部分场合。一个显著的例外是那些会多次重复访问迭代项的代码。容器对象(例如 list)在你每次向其传入 iter() 函数或是在 for 循环中使用它时都会产生一个新的迭代器。如果在此情况下你尝试用迭代器则会返回在之前迭代过程中被耗尽的同一迭代器对象,使其看起来就像是一个空容器。

iterable – 可迭代对象

可以一个一个返回成员的对象。An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict, file objects, and objects of any classes you define with an __iter__() method or with a __getitem__() method that implements sequence semantics.

可迭代对象被可用于 for 循环(for loop)以及许多其他需要一个序列的地方(zip()map() …)。当一个可迭代对象作为参数传给内置函数 iter() 时,它会返回该对象的迭代器。这种迭代器适用于对值集合的一次性遍历。在使用可迭代对象时,你通常不需要调用 iter() 或者自己处理迭代器对象。for 语句会为你自动处理那些操作,创建一个临时的未命名变量用来在循环期间保存迭代器。参见 iteratorsequence 以及 generator

python迭代器概念

b站:【python】对迭代器一知半解?看完这个视频就会了。涉及的每个概念,都给你讲清楚!

iterable和iterator区别:

iterable更像是数据的保存者,一个container,可以不知道迭代器数到哪里了,没有状态,需要有能力产生一个iterator。

iterator是有状态的,但它并不需要实现一个container,内部知道它代表的iterable里面是什么数据,不用实现一个interface接口来修改这个iterable里面的数据。(??)

从实现上看,iterable要么有 __iter__()方法,要么它就是一个sequence,然后有**__getitem__()方法**,这两者都是为了保证可迭代对象可以在iter()这个函数的作用下返回一个迭代器。

iterator必须要有**__next__方法**,这个method保证它在被next()作用下可以返回下一个iterable里面的值。

具体python内部实现过程:for循环里,是从栈顶的iterable里,拿出这个iterable所对应的iterator。

例子,用iterable实现一个链表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class NodeIter:
def __init__(self, Node): # 这里self是自己的nodeiter对象,node是传进来的node对象
self.curNode = Node

def __next__(self):
if not self.curNode:
raise StopIteration
node, self.curNode = self.curNode, self.curNode.next
return node

def __iter__(self):
return self

class Node:
def __init__(self, name):
self.name = name
self.next = None

def __iter__(self):
return NodeIter(self) # 把自己这个Node对象传进去

node1 = Node("a")
node2 = Node("b")
node3 = Node("c")

node1.next = node2
node2.next = node3

for node in node1:
print(node.name)

# 如果想从第二个开始打印:
it = iter(node1)
first = next(it) # 或者写 it.__next__()

for node in it:
print(node.name)

python迭代器语法

b站:『教程』几分钟听懂迭代器

放在for里的对象必须要是可迭代(iterable)的,不然会报错。

有 iter() 方法就是可迭代的。

image-20230202180415065

==对于可迭代对象,for语句会先调用__iter__()方法,然后把__iter__()方法的返回值当成一个对象(obj),并且调用这个对象的__next__()方法(obj.__next__())。==

迭代器(iterator):可迭代对象具有__next__()方法,称为迭代器。或者说,一个对象,有__iter__()方法,也有__next__()方法,则是迭代器。

python中的内置函数iter(),可以得到可迭代对象的迭代器(如果有的话)。

对于迭代器,可直接调用next()方法,来查看每一次的返回值。

举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
>>> a=2233
>>> for e in a:
... print(e)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> from collections.abc import Iterable
>>> isinstance(a, Iterable)
False
>>> lstTest = [1,2,3]
>>> isinstance(lstTest, Iterable)
True
>>> from collections.abc import Iterator
>>> isinstance(lstTest, Iterator)
False
>>> xd = iter(lstTest)
>>> isinstance(xd, Iterator)
True
>>> isinstance(xd, Iterable)
True
>>> xd
<list_iterator object at 0x7f1c07b0c3a0>
>>> xd.__next__()
1
>>> xd.__next__()
2
>>> next(xd)
3
>>> next(xd)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

为什么for循环里不会出现StopIteration异常报错呢?因为for循环里写了自动捕捉这个异常,并把它当作遍历结束的标志:

1
2
3
4
5
6
7
8
9
10
11
# 所以一个for循环:
for i in seq:
do_something_to(i)

# 实际上是这样工作的:
fetch = iter(seq)
while True:
try:
i = fetch.next()
except StopIteration:
break

让自己的类支持迭代:

只需要:

  1. 给类加入__iter__()方法
  2. 上述方法返回的对象具有__next__()方法

举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Reverse:
# 例子:可把字符串反序输出的迭代器
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]

r = Reverse(abc)
print(next(r))
print(next(r))
print(next(r))

# 或者用遍历:
for e in r:
print(e)

# 输出
# c
# b
# a

不知道iter里写什么,就填返回自己(self)。

==迭代器特点:用多少取多少==。这里Reverse(abc)对象只包含abc这三个字符,但每次迭代时只返回【一个】字符,假如这里是三千万个字符,要实现反转的功能,每次迭代时仍然可以只返回一个字符。只要用很少的内存就可以存放和处理!也不需要开辟一个很大的内存空间,来一次性接收这三千万个字符!

又称为“惰性加载”。


realpython教程 Itertools in Python 3, By Example

[1, 2, 3]and 和['a', 'b', 'c']所有列表一样,是可迭代的,这意味着它们可以一次返回一个元素。

从技术上讲,任何实现.__iter__().__getitem__()方法的 Python 对象都是可迭代的。


runoob Python3 迭代器与生成器

迭代是访问集合元素的一种方式。

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter() 和 **next()**。

字符串,列表或元组对象都可用于创建迭代器:

1
2
3
4
5
6
>>> list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> print (next(it)) # 输出迭代器的下一个元素
1
>>> print (next(it))
2

迭代器对象可以使用常规for语句进行遍历:

1
2
3
4
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
for x in it:
print (x, end=" ")

执行以上程序,输出结果如下:

1
1 2 3 4

也可以使用 next() 函数:

1
2
3
4
5
6
7
8
9
10
import sys         # 引入 sys 模块

list=[1,2,3,4]
it = iter(list) # 创建迭代器对象

while True:
try:
print (next(it))
except StopIteration:
sys.exit()

执行以上程序,输出结果如下:

1
2
3
4
1
2
3
4

简书 python 黑科技之迭代器、生成器、装饰器

可迭代对象

先说下上面三者的基础:可迭代对象(Iterable Object),简单的来理解就是可以使用 for 来循环遍历的对象。比如常见的 list、set和dict。可以用以下方法来测试对象是否是可迭代

1
2
3
4
5
6
7
>>> from collections import Iterable
>>> isinstance('abc', Iterable) # 判断str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False

迭代器

对所有的可迭代对象调用 dir() 方法时,会发现他们都实现了 __iter__ 方法。这样就可以通过 iter(object) 来返回一个迭代器。

1
2
3
4
5
6
>>> x = [1, 2, 3]
>>> y = iter(x)
>>> type(x)
<class 'list'>
>>> type(y)
<class 'list_iterator'>

可以看到调用 iter() 之后,变成了一个 list_iterator 的对象。会发现增加了 __next__ 方法。所有实现了 __iter____next__ 两个方法的对象,都是迭代器。

迭代器是带状态的对象,它会记录当前迭代所在的位置,以方便下次迭代的时候获取正确的元素。__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常。


我问chatgpt:python中的迭代器

在 Python 中,迭代器是一种对象,它可以遍历一个集合中的元素,每次返回一个元素,直到元素全部返回或遍历完毕。一个对象是一个迭代器当且仅当它实现了 iter 方法,该方法返回一个实现了 next 方法的对象。 next 方法返回下一个元素,如果没有更多的元素,则抛出 StopIteration 异常。

通过内置函数 iter() 可以将一个对象转换成一个迭代器,通过内置函数 next() 可以从迭代器中返回下一个元素。常见的内置类型如列表、元组、字符串都可以被视为一个迭代器。

以下是一个简单的例子,演示如何创建一个自定义的迭代器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyIterator:
def __init__(self, start, end):
self.current = start
self.end = end

def __iter__(self):
return self

def __next__(self):
if self.current >= self.end:
raise StopIteration
else:
self.current += 1
return self.current - 1

for i in MyIterator(0, 5):
print(i)


待看:

https://www.bilibili.com/video/BV1BT4y1P7nn/?spm_id_from=333.337.search-card.all.click&vd_source=5e9891722f2b62adca440a5e92121b5b