Python迭代器与生成器
1. 迭代器 Iterator
什么是迭代器
- 迭代器是访问集合元素的一种方式。
- 迭代器是一个可以记住遍历的位置的对象。
- 迭代器可以重复使用,而不会像列表那样在迭代时被修改。
迭代器函数iter和next
函数 | 说明 |
---|---|
iter(iterable) | 从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象 |
next(iterator) | 从迭代器iterator中获取下一个记录,如果无法获取一下条记录,则触发 StopIteration 异常 |
迭代器说明 |
- 迭代器对象可以使用
next()
函数获取下一个元素。 - 使用
iter()
函数可以从任何可迭代对象中获取迭代器。
迭代器示例:
# 示例 可迭代对象
L = [1, 2, 3, 4, 5]
it = iter(L) # 从列表L中获取迭代器
print(next(it)) # 输出 1
print(next(it)) # 输出 2
迭代器的用途
- 迭代器对象能用
next()
函数获取下一个元素,这对于大数据集合特别有用,因为它不需要在内存中存储所有元素。
迭代器函数iter和next 示例:
L = [1, 2, 3, 4, 5]
it = iter(L)
for i in it:
print(i)
2. 生成器
生成器是在程序运行时生成数据,与容器不同,它通常不会在内存中保留大量的数据,而是现用现生成。
yield
是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。- 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
- 每次使用
yield
语句生产一个值后,函数都将暂停执行,等待被重新唤醒。 yield
语句相比于return
语句,差别就在于yield
语句返回的是可迭代对象,而return
返回的为不可迭代对象。- 然后,每次调用生成器的
next()
方法或使用for
循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到yield
语句。
生成器函数
含有 yield
语句的函数是生成器函数,此函数调用回返回一个生成器对象,生成器也是可迭代对象
yield
语句的语法
yield 表达式
生成器函数示例1:
def simple_generator():
yield 1
yield 2
yield 3
for value in simple_generator():
print(value)
生成器函数示例2:
def Descendorder(n):
while n > 0:
yield n
n -= 1
# 使用生成器函数
for num in Descendorder(5):
print(num)
以上实例中,Descendorder
函数是一个生成器函数。它使用 yield
语句逐步产生从 n
到 1 的倒序数字。在每次调用 yield
语句时,函数会返回当前的倒序数字,并在下一次调用时从上次暂停的地方继续执行。
创建生成器对象并使用 next()
函数或 for
循环迭代生成器,我们可以逐步获取生成器函数产生的值。在这个例子中,我们首先使用 next()
函数获取前两个倒序数字,然后通过 for
循环获取剩下的三个倒序数字。
生成器函数的优势是它们可以按需生成值,避免一次性生成大量数据并占用大量内存。此外,生成器还可以与其他迭代工具(如 for
循环)无缝配合使用,提供简洁和高效的迭代方式。
1. 生成器表达式
- 语法:
( 表达式 for 变量 in 可迭代对象 [if 真值表达式])
- 作用
用推导式的形式创建一个生成器
示例:
>>> (x ** 2 for x in range(1, 5)) # 生成器表达式
<generator object <genexpr> at 0x...>
>>> for num in (x ** 2 for x in range(1, 5)):
... print(num)
...
1
4
9
16
2. map(函数,可迭代对象)
- 使用一个函数和一个迭代器中的每个元素作为输入,返回一个迭代器,其包含函数应用于每个元素的结果。
示例:
def square(x):
return x ** 2
numbers = [1, 2, 3, 4, 5]
squared_numbers = map(square, numbers)
print(list(squared_numbers)) # 输出 [1, 4, 9, 16, 25]
3. filter(函数,可迭代对象)
- 使用一个函数和一个可迭代对象作为输入,返回一个迭代器,它只包含函数返回值为True的元素。
示例:
def is_even(x):
return x % 2 == 0
numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter(is_even, numbers)
print(list(even_numbers)) # 输出 [2, 4, 6]
4. reduce(函数,可迭代对象[, 初始值])
reduce
函数来自functools
模块,它会对迭代器中的元素进行累积操作,从左到右依次处理数据,最终累计为一个结果值。
示例:
from functools import reduce
def add(x, y):
return x + y
numbers = [1, 2, 3, 4, 5]
sum_of_numbers = reduce(add, numbers)
print(sum_of_numbers) # 输出 15
2. Python装饰器 Decorators
定义:在不修改原始函数代码的情况下,为函数添加新的功能。
2.1 装饰器的基本概念
2.1.1 装饰器语法糖
@decorator
def function():
pass
等价于:
def function():
pass
function = decorator(function)
2.1.2 装饰器示例
def uppercase(func):
def wrapper():
original_result = func()
modified_result = original_result.upper()
return modified_result
return wrapper
@uppercase
def sayhello():
return "Hello, Bob"
print(sayhello()) # 输出 "HELLO, BOB"
2.1.3 带参数的装饰器
def uppercase(func):
def wrapper(*args, **kwargs):
original_result = func(*args, **kwargs)
modified_result = original_result.upper()
return modified_result
return wrapper
@uppercase
def sayhello(name):
return "Hello, " + name
print(sayhello("Bob")) # 输出 "HELLO, BOB"
2.1.4 类装饰器
class MyDecorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("装饰器添加的功能")
return self.func(*args, **kwargs)
@MyDecorator
def sayhello(name):
return "Hello, " + name
print(sayhello("Bob")) # 输出 "装饰器添加的功能" 然后 "Hello, Bob"
MyDecorator
是一个类装饰器。- 它使用
__init__
方法接收一个函数,并将其存储在实例变量self.func
中。 __call__
方法使得类的实例可以被当作函数调用,在这里可以添加额外的功能,并最终调用原始函数。
2.2 装饰器的进阶使用
2.2.1 保留原函数的元信息
当使用装饰器时,原始函数的某些元信息(如函数名、文档字符串、参数列表等)可能会丢失。为了保留这些信息,可以使用 functools.wraps
装饰器。
from functools import wraps
def uppercase(func):
@wraps(func)
def wrapper(*args, **kwargs):
original_result = func(*args, **kwargs)
modified_result = original_result.upper()
return modified_result
return wrapper
@uppercase
def sayhello(name):
"""返回一个问候语"""
return "Hello, " + name
print(sayhello("Bob")) # 输出 "HELLO, BOB"
print(sayhello.__name__) # 输出 "sayhello" 而不是 "wrapper"
print(sayhello.__doc__) # 输出 "返回一个问候语"
2.2.2 嵌套装饰器
可以同时使用多个装饰器来装饰一个函数,装饰器会按照从内到外的顺序执行。
def uppercase(func):
@wraps(func)
def wrapper(*args, **kwargs):
original_result = func(*args, **kwargs)
modified_result = original_result.upper()
return modified_result
return wrapper
def exclamation(func):
@wraps(func)
def wrapper(*args, **kwargs):
original_result = func(*args, **kwargs)
modified_result = original_result + "!"
return modified_result
return wrapper
@uppercase
@exclamation
def sayhello(name):
return "Hello, " + name
print(sayhello("Bob")) # 输出 "HELLO, BOB!"
在这个例子中,sayhello
函数首先被 exclamation
装饰器装饰,然后被 uppercase
装饰器装饰。
2.2.3 装饰器参数的传递
如果装饰器本身需要参数,那么需要再定义一个函数来接收这些参数,然后返回一个装饰器。
def repeat(times):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for _ in range(times):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(times=3)
def sayhello(name):
print("Hello, " + name)
sayhello("Bob") # 输出 "Hello, Bob" 三次
在这个例子中,repeat
函数接收一个参数 times
,然后返回一个装饰器,该装饰器会使得被装饰的函数重复执行指定次数。
2.3 总结
Python的装饰器是一个非常强大的功能,它允许我们在不修改原始函数代码的情况下,增加函数的行为。通过使用装饰器,我们可以轻松地实现日志记录、性能测试、事务处理、权限校验等跨多个函数的通用功能。理解和掌握装饰器是Python高级编程的重要一步。
标签:return,函数,迭代,Python,生成器,10.18,func,def From: https://blog.csdn.net/gs1we1/article/details/143060749