Python 迭代器与生成器

Python 迭代器与生成器

1. 迭代器 Iterator

什么是迭代器

  • 迭代器是访问可迭代对象的工具

  • 迭代器是指用 iter(obj) 函数返回的对象(实例)

  • 迭代器可以用next(it)函数获取可迭代对象的数据

迭代器函数iter和****next

函数说明
iter(iterable)从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象
next(iterator)从迭代器iterator中获取下一个记录,如果无法获取一下条记录,则触发

迭代器说明

  • 迭代器只能往前取值,不会后退

  • 用iter函数可以返回一个可迭代对象的迭代器

迭代器示例:

# 示例 可迭代对象
L = [1, 3, 5, 7]
it = iter(L) # 从L对象中获取迭代器
next(it) # 1 从迭代器中提取一个数据
next(it) # 3
next(it) # 5
next(it) # 7
next(it) # StopIteration 异常
# 示例2 生成器函数
It = iter(range(1, 10, 3))
next(It) # 1
next(It) # 4
next(It) # 7
next(It) # StopIteration
"""
技能迭代器
技能管理器
"""

class SkillIterator:
    def __init__(self,data):
        self.__data = data
        self.__index = -1

    def __next__(self):
        self.__index += 1
        if self.__index > len(self.__data)-1:
            raise StopIteration()
        return self.__data[self.__index]

class SkillManager:
    def __init__(self):
        self.__skills = []

    def add_skill(self,skill):
        self.__skills.append(skill)

    def __iter__(self):
        return SkillIterator(self.__skills)

manager = SkillManager()
manager.add_skill('Python')
manager.add_skill('Java')
manager.add_skill('C++')
manager.add_skill('PHP')

# for skill in manager:
#     print(skill)

# 实现for循环
it = manager.__iter__()
while True:
    try:
        # next(it)
        item = it.__next__()
        print(item)
    except StopIteration:
        break

迭代器的用途

  • 迭代器对象能用next函数获取下一个元素

迭代器函数iter和****next 示例:

L = [2, 3, 5, 7]
it = iter(L)
# 访问列表中的所有元素
while True:
	try:
		print(next(it))
	except StopIteration:
		print("迭代器访问结束")
		break
L = [2, 3, 5, 7]
for x in L:
	print(x)
else:
	print("迭代器访问结束")

2. 生成器

生成器是在程序运行时生成数据,与容器不同,它通常不会在内存中保留大量的数据,而是现用现生成。

  • yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。

  • 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

  • 每次使用 yield 语句生产一个值后,函数都将暂停执行,等待被重新唤醒。

  • yield 语句相比于 return 语句,差别就在于 yield 语句返回的是可迭代对象,而 return 返回的为不可迭代对象。

  • 然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。

生成器可以用算法动态的生成数据

生成器有两种

  1. 生成器函数

  2. 生成器表达式

生成器函数

含有yield 语句的函数是生成器函数,此函数调用回返回一个生成器对象,生成器也是可迭代对象

yield 表达式

生成器函数示例:

# 例1
## 定义一个生成器函数, 有 yield 的函数调用后回返回生成器对象
def myrange(stop):
	i = 0
	while i < stop:
		yield i # 为 遍历次生产器的for 语句提供数据
		i += 1
for x in myrange(5):
	print('x=', x)
    
# 创建一个生成器对象
gen = myrange(5)

# 使用 next() 函数迭代生成器
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))

# 例2
def Descendorder(n):
	while n > 0:
	yield n
	n -= 1
# 创建生成器对象
generator = Descendorder(5)

# 通过迭代生成器获取值
print(next(generator))#5
print(next(generator))#4

# 使用 for 循环迭代生成器
for i in generator:
	print('for循环:', i)#3 2 1

以上实例中,Descendorder 函数是一个生成器函数。它使用 yield 语句逐步产生从 n 到 1 的倒序数字。在每次调用 yield 语句时,函数会返回当前的倒序数字,并在下一次调用时从上次暂停的地方继续执行。

创建生成器对象并使用 next() 函数或 for 循环迭代生成器,我们可以逐步获取生成器函数产生的值。在这个例子中,我们首先使用 next() 函数获取前两个倒序数字,然后通过 for 循环获取剩下的三个倒序数

字。

生成器函数的优势是它们可以按需生成值,避免一次性生成大量数据并占用大量内存。此外,生成器还可以与其他迭代工具(如for循环)无缝配合使用,提供简洁和高效的迭代方式。

生成器表达式

  • 语法:
( 表达式 for 变量 in 可迭代对象 [if 真值表达式])
  • 作用

    用推导式的形式创建一个生成器

  • 示例

>>> [x ** 2 for x in range(1, 5)] # 列表解析(列表推导式)
[1, 4, 9, 16]
>>>
>>> (x ** 2 for x in range(1, 5)) # 生成器表达式
<generator object <genexpr> at 0x7f41dcd30a40>
>>> for y in (x ** 2 for x in range(1, 5)):
... print(y)
...
1
4
9
16

python 函数式编程

定义:用一系列函数解决问题。

  • 函数可以赋值给变量,赋值后变量绑定函数。

  • 允许将函数作为参数传入另一个函数。

  • 允许函数返回一个函数。

1. 函数作为参数

  • 将核心逻辑传入方法体,使该方法的适用性更广。
def func01():
	print("func01执行")
    
# a = func01
# # print(a)
# a()

def func02():
	print("func02执行")
    
# 通用
def func03(func):
	print("func03执行")
	func()
    
func03(func02)
func03(func01)

注释

a = func01 :

  • 变量 a 现在指向 func01 函数对象。

  • a 不是函数的返回值,而是函数对象本身

print(a) :

  • 打印 a ,输出 <function func01 at 0x…> ,表示 a 是一个函数对象,并显示其内存地址。赋值语句 a = func01 并不会执行 func01 函数,只是将函数对象赋值给 a 。调用 a() 或 func01()才会执行函数代码。
list01 = [4, 54, 56, 65, 67, 7]

# 需求1:定义函数,在列表中查找所有大于50的数字
def find01():
	for item in list01:
		if item > 50:
			yield item
            
# 需求2:定义函数,在列表中查找所有小于10的数字
def find02():
	for item in list01:
		if item < 10:
			yield item
            
# “封装” -- 分
def condition01(item):
	return item > 50

def condition02(item):
	return item < 10

# 通用
# “继承” - 隔
def find(func):
	for item in list01:
		# if item < 10:
		# if condition02(item):
		if func(item):
		yield item
        
# "多态" - 做
for item in find(condition01):
	print(item)
    
for item in find(condition02):
	print(item)

总结

1、什么时候使用函数式编程思想?

很多的逻辑或者说核心点是不变的,大多数就是一致的,这个时候我们就可以使用函数式编程思想,可以很好的去定位这个逻辑【函数 式编程思想相对于面向对象编程思想,它更接近于算法】。

2、函数式编程思想替代了面向对象思想?

如果需求中存在多个逻辑变化点时,可以使用类来进行,因为面向对象中存在继承、重写。而函数式编程思想则是将变化点提取到函数 中,实现简单的逻辑。

**lambda ** 表达式

定义:是一种匿名函数

作用:

– 作为参数传递时语法简洁,优雅,代码可读性强。

– 随时创建和销毁,减少程序耦合度。

# 定义:
变量 = lambda 形参: 方法体
# 调用:
变量(实参)

说明:

– 形参没有可以不填

– 方法体只能有一条语句,且不支持赋值语句。

# 1. 有参数有返回值
# def func01(a,b):
# return a > b
#
# print(func01(10,20))
func01 = lambda a,b:a > b
print(func01(10,20))

# 2. 无参数有返回值
# def func02():
# return "ok"
#
# print(func02())
func02 = lambda :"ok"
print(func02())

# 3. 无参数无返回值
# def func03():
# print("ok")
#
# func03()

func03 = lambda :print("ok")
func03()

# 4. 有参数无返回值
# def func03(a):
# print(a)
#
# func03(100)
func03 = lambda a:print(a)
func03(100)

# 5. lambda 不支持赋值语句
# def func05(iterable):
# iterable[0] = 100
#
# list01 = [1]
# func05(list01)
# print(list01)
# func05 = lambda iterable: iterable[0] = 100 报错

# 6. lambda 不支持多条语句
# def func06(a,b):
# print(a)
# print(b)
#
# func06(10,20)
# func06 = lambda a,b: print(a);p
内置高阶函数

定义:将函数作为参数或返回值的函数。

常用:

(1)map(函数,可迭代对象)

  • 使用可迭代对象中的每个元素调用函数,将返回值作为新可迭代对象元素;返回值为新可迭代对象。

(2)filter(函数,可迭代对象)

  • 根据条件筛选可迭代对象中的元素,返回值为新可迭代对象。

(3)sorted(可迭代对象, key=函数, reverse=True)

  • 排序,返回值为排序后的列表结果。

(4)max(可迭代对象, key = 函数)

  • 根据函数获取可迭代对象的最大值。

(5)min(可迭代对象,key = 函数)

  • 根据函数获取可迭代对象的最小值。
class Girl:
	def __init__(self, name="", face_score=0, age=0,height=0):
		self.name = name
		self.face_score = face_score
		self.age = age
		self.height = height
	def __str__(self):
		return "%s-%d-%d-%d" % (self.name,self.face_score, self.age,self.height)
    
list_girl = [
	Girl("双儿", 96, 22, 166),
	Girl("阿珂", 100, 23, 173),
	Girl("小郡主", 96, 22, 161),
	Girl("方怡", 86, 27, 166),
	Girl("苏荃", 99, 31, 176),
	Girl("建宁", 93, 24, 163),
	Girl("曾柔", 88, 26, 170),
]

# 1. map 映射
# 在美女列表中获取所有名称
# 类似于:select
for element in map(lambda item: item.name, list_girl):
	print(element)
    
# 2. filter 过滤器
# 在美女列表中获取颜值大于90的所有美女
# 返回的是符合条件的对象的所以属性
# 类似于:find_all
for element in filter(lambda item: item.face_score > 90, list_girl):
	print(element)

# 3. max/min
# 在美女列表中获取颜值最高的美女
# 类似于:get_max
print(max(list_girl,key = lambda item:item.face_score))
print(min(list_girl,key = lambda item:item.face_score))
# 4.sorted 排序
# 注意:没有改变原有列表,而是返回新的
# 升序
for item in sorted(list_girl,key = lambda item:item.height):
	print(item)
# 降序
for item in sorted(list_girl,key = lambda item:item.height,reverse=True):
	print(item)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值