(一)迭代器
迭代器是一种对象,该对象包含值的可计数数字。
迭代器是可迭代的对象,这意味着您可以遍历所有值。
从技术上讲,在 Python 中,迭代器是实现迭代器协议的对象,它包含方法 iter() 和 next()。
列表、元组、字典和集合都是可迭代的对象。它们是可迭代的容器,您可以从中获取迭代器(Iterator)。
所有这些对象都有用于获取迭代器的 iter() 方法:
也可以使用for循环,循环遍历可迭代对象。
当迭代器已经将可迭代对象里面的数据都读取完了,你再使用next方法就会报错StopIteration。
如果一个对象实现了__iter__
方法,那么它就是一个可迭代对象。
如果一个对象实现了__iter__
和__next__
方法,那么它就是一个迭代器。
list1 = [1,2,3,4,5]
str1 = "abcdefg"
it1 = iter(list1)
it2 = iter(str1)
print(next(it1)) # 1
print(next(it2)) # a
for i in it1:
print(i) # 2 3 4 5
print(next(it1)) # StopIteration:
# 自定义迭代器
class MyNumber:
def __init__(self,start=0, value=0, step=1) -> None:
if start > value:
raise Exception("开始值不能大于结束值!")
self.value = value
self.step = step
self.start = start
def __iter__(self):
self.index = self.start
self.x = None
return self # 必须要返回迭代器对象本身
def __next__(self):
if self.index < self.value:
self.x = self.index
self.index += self.step
return self.x
else:
# print("结束了")
raise StopIteration
for i in MyNumber(-5,5,2): # 创建了一个类似range类的MyNumber类
print(i)
# 等同于
for i in range(-5,5,2): # 左闭右开[-5, 5)
print(i)
所以根据上面的代码我们可以得出for循环的工作流程。
- 调用该对象的iter方法获取迭代器
- 调用next方法,获取迭代值
- 捕获StopIteration异常,结束循环
- 执行for循环里的代码
生成器
其实生成器也是一种迭代器,但是它是一种特殊的迭代器。他的功能是,我们每调用一次就会返回一个值,这个值是调用的时候生成的,并不是提前准备好的。
(1)二者区别
1.迭代器是访问容器的一种方式,也就是说容器已经出现。我们是从已有元素拓印出一份副本,只为我们此次迭代使用。而生成器则是,而生成器则是自己生成元素的。也就是前者是从有到有的复制,而后者则是从无到有的生成。以 list 容器为例,在使用该容器迭代一组数据时,必须事先将所有数据存储到容器中,才能开始迭代;而生成器却不同,它可以实现在迭代的同时生成元素。
2.在用法上生成器只需要简单函数写法,配合yield就能实现。而迭代器真正开发中很难使用到。我们可以把生成器看做,python给我们提供的特殊接口实现的迭代器。
(2)如何定义一个生成器
不仅如此,生成器的创建方式也比迭代器简单很多,大体分为以下 2 步:
- 定义一个以 yield 关键字标识返回值的函数;
- 调用刚刚创建的函数,即可创建一个生成器;
下面的代码分别使用生成器实现range和zip的功能。
def generators(start=0, value=0, step=0):
if start > value:
raise Exception("开始值不能大于结束值!")
while start < value:
yield start
start = start+step
for i in generators(-5,5,2):
print(i)
list1 = ["a","b","c"]
list2 = [1,2,3,4]
def my_zip(*lists):
min_len = min([len(l) for l in lists])
index=0
while min_len:
yield tuple([x[index] for x in lists])
index+=1
min_len-=1
dict1 = {}
for x,y in my_zip(list1,list2):
dict1[x] = y
print(dict1) # {'a': 1, 'b': 2, 'c': 3}
网友评论