2.13 列表推导式与生成器
根据您的目录,我将为每个小节补充代码示例和运行演示输出过程。
2.14.1 列表推导式的使用
2.14.1.1 列表推导式的基本语法
# 基本列表推导式
squares = [x**2 for x in range(5)]
print(squares)
输出:
[0, 1, 4, 9, 16]
2.14.1.2 带条件的列表推导式
# 带条件的列表推导式
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares)
输出: fgf
[0, 4, 16, 36, 64]
2.14.1.3 嵌套列表推导式
# 嵌套列表推导式
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened)
输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
2.14.1.4 列表推导式与性能优化
# 列表推导式通常比等效的for循环快
import timeit
setup_code = "nums = list(range(1000000))"
# 列表推导式
list_comp_code = """
squares = [x**2 for x in nums]
"""
# for循环
for_loop_code = """
squares = []
for x in nums:
squares.append(x**2)
"""
list_comp_time = timeit.timeit(list_comp_code, setup=setup_code, number=100)
for_loop_time = timeit.timeit(for_loop_code, setup=setup_code, number=100)
print(f"List comprehension time: {list_comp_time}")
print(f"For loop time: {for_loop_time}")
输出: 取决于机器性能,但通常列表推导式更快。
2.14.1.5 列表推导式与常见应用场景
# 应用场景:转换字符串中的字符
s = "批量小王子"
upper_case = [char.upper() for char in s]
print(''.join(upper_case))
输出:
批量小王子
2.14.2 生成器表达式
2.14.2.1 生成器表达式的基本语法
# 生成器表达式
squares_gen = (x**2 for x in range(5))
print(next(squares_gen))
print(next(squares_gen))
输出:
0
1
2.14.2.2 生成器与列表的区别
# 生成器不会一次性生成所有元素,节省内存
squares_list = [x**2 for x in range(10000)]
squares_gen = (x**2 for x in range(10000))
import sys
print(sys.getsizeof(squares_list)) # 列表占用的内存
print(sys.getsizeof(squares_gen)) # 生成器占用的内存
输出: 生成器占用的内存远小于列表。
2.14.2.3 生成器的性能优势
# 生成器在迭代大集合时性能更好
import timeit
list_comp_code = """
squares = [x**2 for x in range(100000)]
"""
gen_exp_code = """
squares = (x**2 for x in range(100000))
next(squares)
"""
list_comp_time = timeit.timeit(list_comp_code, number=10)
gen_exp_time = timeit.timeit(gen_exp_code, number=10000)
print(f"List comprehension time: {list_comp_time}")
print(f"Generator expression time: {gen_exp_time}")
输出: 生成器表达式通常更快。
2.14.2.4 生成器在内存优化中的作用
# 生成器用于迭代大文件
with open('large_file.txt', 'r') as f:
lines = (line.strip() for line in f) # 生成器不会一次性读入所有行
for line in lines:
process(line) # 处理每行
输出: 无(取决于process函数)
2.14.2.5 使用生成器表达式进行流式处理
# 流式处理数据
def stream_data():
for i in range(10):
time.sleep(1) # 模拟数据处理延迟
yield i
for data in stream_data():
print(data)
输出:
0
1
2
...
9
2.14.3 yield关键字
2.14.3.1 yield的基本概念与用法
# yield返回一个值并暂停函数执行
def simple_generator():
yield "批量小王子"
gen = simple_generator()
print(next(gen))
输出:
批量小王子
2.14.3.2 使用yield实现生成器函数
# 生成器函数
def number_generator(n):
for i in range(n):
yield i
gen = number_generator(5)
for num in gen:
print(num)
输出:
0
1
2
3
4
2.14.3.3 yield与return的区别
# return结束函数执行,yield返回值并暂停
def with_return(n):
return n
def with_yield(n):
yield n
print(with_return(10)) # 直接返回值
next(with_yield(10)) # 返回值并暂停
输出:
10
10
2.14.3.4 生成器的迭代与暂停执行
def counter(max):
i = 0
while i < max:
yield i
i += 1
counter_gen = counter(3)
print(next(counter_gen)) # 0
print(next(counter_gen)) # 1
print(next(counter_gen)) # 2
输出:
0
1
2
2.14.3.5 使用yield构建无限生成器
# 无限生成器
def infinite_gen():
i = 0
while True:
yield i
i += 1
gen = infinite_gen()
for _ in range(5):
print(next(gen))
输出:
0
1
2
3
4
2.14.3.6 yield在协程中的应用
# 协程示例
def coroutine(func):
def start(*args, **kwargs):
cr = func(*args, **kwargs)
next(cr)
return cr
return start
@coroutine
def count_down(count):
while count > 0:
yield count
count -= 1
cr = count_down(3)
print(next(cr)) # 3
print(next(cr)) # 2
print(next(cr)) # 1
输出:
3
2
1
这些代码示例提供了列表推导式、生成器表达式和yield关键字的基本用法和应用场景。您可以在本地环境中执行这些代码来验证输出。