目录
1、迭代器
迭代器允许逐个访问集合中的元素,而无需一次性加载集合中的所有元素。
无论是python内置迭代器,还是自定义迭代器,都实现了__iter__和__next__方法。其中,
__iter__:用于返回一个迭代器对象。
__next__:用于返回集合中的下一个元素,当没有更多元素时,会抛出异常StopIteration
,表示迭代结束。
1.1 内置迭代器
for循环是python内置的一个迭代器,可用于遍历集合数据类型,如列表(list),元组(tuple),集合(set),字符串(str),字典(dict)。其中,字典遍历的是键,如果想遍历键值对,可以用dict.item()。
上述提到的可用于for循环的内置数据类型,都是可迭代对象,拥有__iter__方法和__next__方法。下面代码,列举了三种数据类型,分别用for循环和next(迭代器对象)方式遍历打印集合中的元素。
#列表
list1 = [1,2,3,4]
#for循环方式遍历
for i in list1:
print('for循环:',i)
#迭代器对象遍历
list1_iterator = iter(list1)
for j in range(4):
print("迭代器:",next(list1_iterator))
#字符串
str1 = "abcd"
for i in str1:
print('for循环:',i)
str1_iterator = iter(str1)
for j in range(4):
print("迭代器:",next(str1_iterator))
#字典
dict1 = {"a":1,"b":2}
for i,j in dict1.items():
print("for循环:",(i,j))
dict1_iterator = iter(dict1)
for j in range(3):
print("迭代器:",next(dict1_iterator))
进一步理解两个概念,可迭代对象和迭代器对象。这里以列表(list)为例,
from typing import Iterable, Iterator
list1 = [1,2,3,4]
print("list1是否是可迭代对象:",isinstance(list1,Iterable))
print("list1是否是迭代器:",isinstance(list1,Iterator))
list1_iterator = iter(list1)
print("list1是否是可迭代对象:",isinstance(list1_iterator,Iterable))
print("list1是否是迭代器:",isinstance(list1_iterator,Iterator))
执行上述代码后,打印内容如下。可以看出,list是可迭代对象,但不是迭代器;经过__iter__方法后,变成了迭代器,同时也是可迭代对象。
list1是否是可迭代对象: True
list1是否是迭代器: False
list1是否是可迭代对象: True
list1是否是迭代器: True
1.2 自定义迭代器
通过了解python中内置的可迭代对象,以及通过内置__iter__方法生成了迭代器,在经过内置__next__方法遍历迭代器对象中的元素。这部分内容创建属于我们自己的迭代器。
下面代码中,创建了一个自定义迭代器类custom_iterator,其中,
__init__:类实例化对象的初始化操作。
__iter__:返回迭代器对象。return self 用于方法链式调用,它的作用是返回当前对象实例,可在一个表达式中连续调用方法。
__next__:自定义的遍历数据方法。
class custom_iterator:
def __init__(self,data):
self.data = data
self.count = 0
def __iter__(self):
return self
def __next__(self):
#越界抛出异常
if self.count >= len(self.data):
raise StopIteration
else:
value = self.data[self.count]
self.count = self.count + 1
return value
str1 = "abcd"
str1_iterator = custom_iterator(str1)
print("str1_iterator是否是迭代器:",isinstance(str1_iterator,Iterator))
print(str1_iterator.__next__())
print(str1_iterator.__next__())
执行代码后,输出如下。可以看到,对类实例化后的对象, 默认已经执行了__iter__操作,生成的是一个迭代器对象,可直接使用__next__方法遍历数据集。
str1_iterator是否是迭代器: True
a
b进程已结束,退出代码0
2、生成器
生成器是一个特殊类型的迭代器,它可在迭代过程中逐步生成元素,无需一次性产生所有元素,在进行迭代,能够节省内存。
2.1 创建生成器
在python中,创建生成器有两种方式,分别是生成器表达式和生成器函数。
2.1.1 生成器表达式
生成器表达式使用圆括号来创建,它生成一个生成器对象,示例如下
gen1 = (x for x in range(100))
2.1.2 生成器函数
创建生成器函数,需要用到yield表达式,来生成序列中的值。每次调用碰到yield语句时,会暂听执行函数,并返回yield语句后面的值,等到下一次调用时,会从暂停处继续执行。
def custom_generator():
yield 1
yield 2
yield 3
# 生成器对象
gen = custom_generator()
2.2 遍历生成器
生成器是一种特殊的迭代器,两个具有相同的遍历方式。
2.2.1 next方法遍历
next方法,两种形式都可用。一种是直接next(生成器对象) ,另一种是生成器对象.__next__都可
def custom_generator():
yield 1
yield 2
yield 3
# 生成器对象
gen = custom_generator()
print(next(gen))
print(next(gen))
print(next(gen))
运行结果如下,非常简单,每次遍历都会在yield处暂停,并输出yield语句后面紧跟着的值。
1
2
3进程已结束,退出代码0
2.2.2 for循环遍历
生成器本身也是一个可迭代对象,所以可直接使用for循环依次输出
def custom_generator():
yield 1
yield 2
yield 3
# 生成器对象
gen = custom_generator()
for i in gen:
print("输出:",i)
执行结果如下
是否是可迭代对象: True
是否是迭代器: True
输出: 1
输出: 2
输出: 3进程已结束,退出代码0