Python(十):第九章:迭代器、生成器与推导式

第九章:迭代器、生成器与推导式

9.1 迭代器

迭代器是一种可以被遍历的对象,它实现了 __iter__()__next__() 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 获取迭代器的两种方式
# 方法一:使用iter()函数
iter_str = iter("Python") # 将字符串转换为迭代器
# 使用next()函数获取迭代器的元素
print(next(iter_str)) # 输出:'P'
print(next(iter_str)) # 输出:'y'
print(next(iter_str)) # 输出:'t'
print(next(iter_str)) # 输出:'h'
print(next(iter_str)) # 输出:'o'
print(next(iter_str)) # 输出:'n'
# 也可以通过for循环获取迭代器的元素
for char in iter_str:
print(char) # 在这里不会输出了,因为迭代器的元素已经被上方取完了


# 方法二:使用__iter__()方法
# 在Python中,所有的元素都会有一个默认的__iter__()方法,该方法返回一个迭代器对象,该对象可以用来获取元素。
# 因此,如果一个对象实现了__iter__()方法,那么它就可以被转换为迭代器。
iter_str2 = "Python".__iter__() # 调用字符串的__iter__()方法,将字符串转换为迭代器
print(iter_str2.__next__()) # 输出:'P'

# 迭代完成后会抛出StopIteration异常
try:
while True:
print(next(iter_str2))
except StopIteration:
print("迭代完成")

自定义迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CountDown:
def __init__(self, start):
self.start = start

def __iter__(self):
return self

def __next__(self):
if self.start <= 0:
raise StopIteration
self.start -= 1
return self.start + 1

# 使用自定义迭代器
counter = CountDown(5)
for num in counter:
print(num) # 输出: 5, 4, 3, 2, 1

for 循环的工作原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# for循环实际上是这样工作的:
def my_for(iterable, callback): # iterable是可迭代对象,callback是一个回调函数,每一次迭代都会调用这个函数
#通过iter()函数将"abc"转换成一个迭代器
iterator = iter(iterable)
while True:
try:
# 无限循环,直到迭代器结束
item = next(iterator)
# 调用回调函数
callback(item)
except StopIteration:
break


# 例如:
my_for("abc", lambda x: print(x))
# 等价于
for x in "abc":
print(x)

9.2 生成器

生成器是一种特殊的迭代器,使用 yield 语句而不是 return 语句返回值。每次调用 next() 时,生成器函数从上次离开的地方继续执行

yield 相比较 return 关键字在于 yield 属于“等一下再离开”,每次调用 yield 都会返回不同的值,也就是每一次循环便利都会返回下一个 yield,直到没有

在这里我们简单的了解一下 yield 关键字,到了并发编程中,yiled 还会有一些常见的用途,如:

1、形成生成器

2、协程

3.上下文管理器

4、yield from

1
2
3
4
5
6
7
8
9
10
11
# 简单的生成器函数
def simple_generator():
yield 1
yield 2
yield 3

gen = simple_generator()
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3
# print(next(gen)) # 抛出StopIteration

生成器表达式(推导式)

1
2
3
4
5
6
# 生成器表达式
even_numbers = (x for x in range(10) if x % 2 == 0)

# 使用生成器
for num in even_numbers:
print(num) # 输出: 0, 2, 4, 6, 8

生成器的优势

  1. 内存效率:生成器不会一次性生成所有值,而是按需生成,降低内存使用
  2. 延迟计算:只有在请求下一个值时才执行计算
  3. 无限序列:可以表示理论上无限的数据流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 内存效率示例
# 传统列表方式
def get_lines_list(file_path):
result = []
with open(file_path, 'r') as f:
for line in f:
result.append(line.strip())
return result

# 生成器方式
def get_lines_generator(file_path):
with open(file_path, 'r') as f:
for line in f:
yield line.strip()

生成器应用场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 批量处理示例
def batch_processor(items, batch_size=100):
"""将大列表分成小批次处理"""
batch = []
for item in items:
batch.append(item)
if len(batch) == batch_size:
yield batch
batch = []
if batch: # 处理最后不满batch_size的批次
yield batch

# 使用
items = list(range(1050))
for batch in batch_processor(items, 300):
print(f"处理批次,大小: {len(batch)}")

9.3 推导式

推导式是创建数据集合的简洁方法。

列表推导式

1
2
3
4
5
6
7
8
9
10
11
12
# 基本语法
[表达式 for 变量 in 可迭代对象 if 条件]

# 示例
squares = [x**2 for x in range(1, 11)] # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

# 带条件过滤
even_squares = [x**2 for x in range(1, 11) if x % 2 == 0] # [4, 16, 36, 64, 100]

# 多层推导式
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [x for row in matrix for x in row] # [1, 2, 3, 4, 5, 6, 7, 8, 9]

字典推导式

1
2
3
4
5
6
7
8
9
# 基本语法
{键表达式: 值表达式 for 变量 in 可迭代对象 if 条件}

# 示例
squares_dict = {x: x**2 for x in range(1, 6)} # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# 键值互换
original = {'a': 1, 'b': 2, 'c': 3}
inverted = {v: k for k, v in original.items()} # {1: 'a', 2: 'b', 3: 'c'}

集合推导式

1
2
3
4
5
6
7
8
9
# 基本语法
{表达式 for 变量 in 可迭代对象 if 条件}

# 示例
squares_set = {x**2 for x in range(1, 11)} # {1, 4, 9, 16, 25, 36, 49, 64, 81, 100}

# 去除重复元素
words = ['hello', 'world', 'hello', 'python']
unique_lengths = {len(word) for word in words} # {5, 6}

生成器表达式

1
2
3
4
5
6
7
8
# 基本语法
(表达式 for 变量 in 可迭代对象 if 条件)

# 示例
squares_gen = (x**2 for x in range(1, 11))

# 在函数调用中使用(不需要额外括号)
sum_of_squares = sum(x**2 for x in range(1, 11)) # 385

三元表达式

1
2
3
4
5
6
7
8
9
10
# 基本语法
1 if 条件 else2

# 示例
x, y = 10, 20
larger = x if x > y else y # y

# 在推导式中使用
values = [1, 2, 3, 4, 5]
result = [x*2 if x % 2 == 0 else x*3 for x in values] # [3, 4, 9, 8, 15]