Python学习笔记:2.2.1 迭代器和生成器

本文是学习《Python全栈工程师》课程的笔记,重点讲解了迭代器和生成器的概念及应用。文章阐述了迭代的定义,列举了迭代器的典型应用,并介绍了如何判断一个对象是否为可迭代对象。接着,详细说明了迭代器的工作原理,包括如何创建和使用迭代器。此外,还探讨了生成器的特点,通过编写斐波那契数列的迭代器和生成器实例进行说明。
摘要由CSDN通过智能技术生成

本文是学习齐老师的《python全栈工程师》课程的笔记,欢迎学习交流。同时感谢齐老师的精彩传授!

一、课程目标
  • 理解迭代器的含义和应用
  • 理解生成器的含义和应用
二、详情解读

01.迭代器:
迭代(iteration): 迭代是重复反馈过程的活动,其目的通常是为了接近并到达所需的目标或结果。每一次对过程的重复被称为一次”迭代“,而每一次迭代得到的结果会被用来作为下一次迭代的初始值。

典型应用:”牛顿法“求根:
x m − a = 0 设 : f ( x ) = x m − a , f ′ ( x ) = m x m − 1 x n + 1 = x n − f ( x n ) f ′ ( x n ) 则 x n + 1 不 断 逼 近 a 的 m 次 方 根 x^m - a = 0 \\ 设:f(x) = x^m - a, \\ f{'}(x) = mx^{m-1}\\ x_{n+1} = x_n - \frac{f(x_n)}{f{'}(x_n)}\\ 则x_{n+1}不断逼近a的m次方根 xma=0f(x)=xma,f(x)=mxm1xn+1=xnf(xn)f(xn)xn+1am

value = 23
epsilon = 0.001
result = value / 2
while abs(result * result - value) >= epsilon:
	result = result - ((result*result - value) / ( 2 * result))
print('The square root of {0} is about {1}'.format(value, result))

import math
print(math.sqrt(23))

可迭代对象: 是指能够逐一返回其成员的对象。主要包括:所有序列类型(例如list,str 和 tuple)、某些非序列类型例如 dict和文件对象、还有定义了__iter__()方法或是实现了Sequence 语义的__getitem__()方法的任意自定义类对象。一般用__iter__判断是否是可迭代对象。

可迭代对象用于for循环以及某些对象的参数比例如map等。

print(hasattr(list, '__iter__')) # True
r = range(0, 10)
print(hasattr(r, '__iter__')) # True

迭代器(iterator):

  • 用来表示一连串数据流的对象。重复调用迭代器的__next__()方法(或将其传给内置函数 next())将逐个返回流中的项。当没有数据可用时则将引发StopIteration异常。
  • 迭代器必须具有__iter__()方法用来返回该迭代器对象自身,因此迭代器必定也是可迭代对象。
  • 使用内置函数iter()创建迭代器对象。
  • 判断:iter__和__next
lst = [1,2,3]
print(hasattr(lst, '__iter__')) # True
print(hasattr(lst, '__next__')) # False 说明列表是可迭代的,但不是迭代器

iter_lst = iter(lst) # 创建迭代器对象
print(hasattr(iter_lst, '__iter__')) # True
print(hasattr(iter_lst, '__next__')) # True
print(iter_lst.__next__()) # 1
print(iter_lst.__next__()) # 2
print(iter_lst.__next__()) # 3
print(iter_lst.__next__()) # 报 StopIteration异常

# 注意遍历迭代器时,数据流是否已经读取完毕
for i in iter_lst:
	# 此处打印为空,因为上面的__next__()操作,已经将数据流读取完毕了,相当于指针已经指到最后了
	# 这里不报错是因为for循环自动捕获并处理了stopIteration异常了
	print(i)
# 为了解决上面提到的问题,简单粗暴的方法是重新创建一个迭代器对象
iter_lst = iter(lst)
for i int iter_lst:
	print(i) # 1 2 3

迭代器的执行过程:
在这里插入图片描述
补充for循环的发生过程
在这里插入图片描述
例题1:

编写斐波那契数列的迭代器对象。

class Fibs:
	def __init__(self, max):
		self.max = max
		self.a = 0
		self.b = 1
	def __iter__(self):
		return self
	def __next__(self):
		fib = self.a
		if fib > self.max:
			raise StopIteration
		self.a, self.b = self.b, self.a + self.b
		return fib

fibs = Fibs(100000)
lst = [fibs.__next__() for i in range(10)]
print(lst) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
# 还有一种创建迭代器的方法
import itertools
c = itertools.count(start=3) # 从3 开始到无限大
print(next(c)) # 3 
printable(next(c)) # 4

colors = itertools.cycle(['red', 'yellow', 'blue'])
print(next(colors)) # red
print(next(colors)) # yellow
print(next(colors)) # blue
print(next(colors)) # red 以此循环下去

02.生成器:
生成器(generator): 类似普通函数,不同点在于其包含yield表达式,生成器也是迭代器。

# 普通函数
def r_return(n):
	while n > 0:
		print('before return')
		return n
		n -= 1
		print('after return')
re = r_return(3) # before return
print(re) # 3

# 生成器
def y_yield(n):
	while n > 0:
		print('before yield')
		yield n
		n -= 1
		print('after yield')
yy = y_yield(3) # 创建一个迭代器对象(也是生成器)
print(yy.__next__()) # before yield     3
print(yy.__next__()) # after yield      before yield    2
print(yy.__next__()) # after yield      before yield    1
print(yy.__next__()) # 先打印 after yield,然后报错,因为指针已经移动到迭代器的最尾端了

例题2:

编写斐波那契数列的生成器函数。

def fibs():
	prev, curr = 0, 1
	while True:
		yield prev
		prev, curr = curr, prev + curr
import itertools
print(list(itertools.islice(fibs(), 10))) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

生成器解析:

# 列表解析:
lst = [x ** 2 for x in range(10)]
print(lst) # [0,1,4,9,16,25,36,49,64,81]

# 生成器解析
gt = (x ** 2 for x in range(10))
print(gt)  # <generator object <genexpr> at 0x105e9ee60>
三、课程小结
  • 学习了迭代器
  • 学习了生成器
四、作业

内置函数range 的参数必须是整数。请编写一个生成器函数,以浮点数为参数(开始值,结束值,步长)生成某范围的序列。

def y_range(start, end, step=1):

  while start < end:
    yield start
    start = start + step

import itertools
start = 0.2
end = 11
step = 2.5
n = round((end-start)/step) + 1
lst = list(itertools.islice(y_range(start, end, step), n))
print(lst)  # [0.2, 2.7, 5.2, 7.7, 10.2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值