2.12_列表推导式与生成器

134 阅读4分钟

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 yieldreturn的区别

# 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关键字的基本用法和应用场景。您可以在本地环境中执行这些代码来验证输出。

4-1-2.png