24/9/21 python的推导式、生成器
python推导式和生成器
介绍
1. 列表推导式(List Comprehension)
列表推导式是最常见的一种推导式,它允许你用一行代码生成列表,形式如下:
new_list = [expression for item in iterable if condition]
expression
:要添加到新列表的值,可以是简单的变量,也可以是运算结果。item
:来自迭代对象的每个元素。iterable
:任何可迭代对象(如列表、字符串、range 等)。if condition
:可选,用来筛选符合条件的元素。
示例:
生成一个包含平方数的列表:
squares = [x**2 for x in range(10)]
print(squares) # 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
2. 字典推导式(Dictionary Comprehension)
字典推导式与列表推导式类似,只不过它生成的是字典,格式如下:
new_dict = {key: value for item in iterable}
示例:
生成一个键为数字,值为其平方的字典:
squares_dict = {x: x**2 for x in range(5)}
print(squares_dict) # 输出 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
3. 集合推导式(Set Comprehension)
集合推导式的语法与列表推导式类似,但生成的结果是集合。
new_set = {expression for item in iterable if condition}
示例:
生成一个不重复的平方数集合:
squares_set = {x**2 for x in range(5)}
print(squares_set) # 输出 {0, 1, 4, 9, 16}
4. 生成器表达式(Generator Expression)
生成器表达式和列表推导式类似,但它不直接生成列表,而是返回一个生成器对象,用于惰性求值,适合处理大量数据。
gen = (x**2 for x in range(10))
print(list(gen)) # 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
5. 嵌套推导式
推导式也可以嵌套,用于生成复杂的结构。
示例:
生成一个二维列表:
matrix = [[i * j for j in range(3)] for i in range(3)]
print(matrix) # 输出 [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
总结:
推导式使代码更加简洁、可读,并且在处理生成列表、字典或集合时特别高效。不过,推导式过于复杂时可能会影响代码的可读性,需谨慎使用。
1. 什么是生成器?
生成器(Generator) 是 Python 中一种特殊类型的迭代器,用于生成一系列的值。在常规的函数中,使用 return
来返回值并结束函数,而在生成器中,使用 yield
来逐次生成值,而不终止函数。生成器可以暂停函数的执行,并在下一次迭代时恢复执行,这种特性使得它适用于处理大量数据或无限数据流。
生成器的定义:
- 生成器可以通过生成器函数创建,使用
yield
语句。 - 生成器也可以通过生成器表达式创建,类似于列表推导式,但使用圆括号代替方括号。
生成器函数示例:
def my_generator():
yield 1
yield 2
yield 3
gen = my_generator()
for value in gen:
print(value)
2. 生成器与列表的区别
-
内存占用:
- 生成器是惰性求值的,这意味着它们不会一次性把所有的值加载到内存中,而是每次需要时才生成下一个值,因此非常节省内存。
- 列表则会在创建时一次性将所有元素加载到内存中,尤其是当数据量很大时,可能导致大量的内存占用。
-
求值方式:
- 生成器是惰性求值的(即在需要时才生成下一个值),而列表是即时求值的(一次性生成整个列表的所有值)。
-
可重复使用:
- 生成器一旦迭代完毕,就不能再次使用,除非重新创建。
- 列表可以多次迭代,因为它们的所有元素都存储在内存中。
列表与生成器的对比:
# 列表
lst = [x**2 for x in range(5)]
print(lst) # 输出: [0, 1, 4, 9, 16]
# 生成器
gen = (x**2 for x in range(5))
print(list(gen)) # 输出: [0, 1, 4, 9, 16]
生成器不占用大量内存,但在将生成器转换为列表时,才会将所有值存储在内存中。
3. 什么是惰性求值?
惰性求值(Lazy Evaluation),也叫延迟求值,是一种计算策略,指的是当值真正被需要时才进行计算,而不是在定义时立即计算。这使得生成器可以在处理大量数据或无限序列时显得特别高效。
惰性求值的好处:
- 节省内存:生成器不会立即生成所有元素,只在迭代到某个值时才计算它,因此适合处理大规模或无限数据流。
- 提高效率:通过按需生成数据,避免了不必要的计算和内存占用。
示例:
def count_up_to(n):
count = 1
while count <= n:
yield count
count += 1
counter = count_up_to(5)
print(next(counter)) # 1
print(next(counter)) # 2
# 生成器不会计算后续的值,直到你需要它们为止
在此例中,生成器在调用 next()
时才生成下一个值,未被调用时不会生成,因此更高效。
总结:
- 生成器是惰性求值的迭代器,用来节省内存并延迟计算。
- 列表是立即求值的,它会一次性加载所有元素。
- 惰性求值是指在需要时才进行计算,而不是立即执行,从而提高性能和内存使用效率。
生成器特别适用于大规模或无限序列的处理场景,因为它们仅在需要时生成数据,非常节省内存。