推导式
利用 []
或者 {}
可以定义列表推导式、集合/字典推导式,推导式的结果就是相应的列表,字典/集合数据类型。注意是没有元组推导式的,因为圆括号 ()
被用来作为生成器表达式语法了。
列表推导式 List Comprehension
用方括号 [ ]
包含内容,里面利用 for [if]
循环和相应的函数生成相应序列
# 单循环
example_01 = [x * 2 for x in range(10)] # 创建列表推导式
print(example_01)
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# 双循环
example_02 = [(i,j) for i in range(3) for j in range(5)] # 创建列表推导式
print(example_02)
# [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4)]
# for if 表达式
symbols = 'abcdef'
nums_big = [ord(symbol) for symbol in symbols if ord(symbol) > 98]
# [99, 100, 101, 102]
集合生成式 ( Set Comprehension)
用花括号 {}
包含内容,里面利用 for [if]
循环和相应的函数生成相应集合
numbers = [1,2,3,4,5,]
{x * x for x in numbers}
# {1, 4, 9, 16, 25}
字典生成式 ( (Dict Comprehension)
也是用花括号 {}
包含内容,但是里面是利用 for [if]
循环和相应的函数生成相应字典:
numbers = [1,2,3,4,5,]
{x : x * x for x in numbers}
# {1:1, 2:4, 3:9, 4:16, 5:25}
生成器表达式
除了有一种称之为 “惰性计算” 的特点以外,生成器表达式和推导式的用法基本一致,只不过是把方括号/花括号换成了一对圆括号 ()
。
example_03 = (x * 2 for x in range(10) if x % 2 == 1) # 创建生成器表达式
print(example_03) # 实际调用生成器时代码并不会立即执行
输出:<generator object <genexpr> at 0x000001AACF7D3CF0>
for x in example_03:
print(x,end = ' ')
输出:2 6 10 14 18
两者区别
-
生成器表达式本质上是一个生成器,它每次生成一个元素,而不是一下生成全部数据。这个特性叫作“惰性计算”,优点是可以节省大量的内存,在处理的数据量较大时,非常有用。相比之下,推导式是直接生成全部数据。
-
列表推导式可以多次迭代,生成器表达式只能单次迭代(符合生成器的一般特性,生成器结束后再调用
next()
函数会抛出StopIteration
异常)
# 列表推导式
example_04 = [x for x in range(10)] # 获取 0 - 9 的序列
# 第一次调用
for x in example_04:
print(x,end = ' ')
# 0 1 2 3 4 5 6 7 8 9
# 第二次调用
for x in example_04:
print(x,end = ' ')
# 0 1 2 3 4 5 6 7 8 9
# 生成器表达式
example_05 = (x for x in range(10))
# 第一次调用
for x in example_05:
print(x,end = ' ')
# 0 1 2 3 4 5 6 7 8 9
# 第二次调用 注意与列表推导式的区别
for x in example_05:
print(x,end = ' ')
# 无输出
Reference
- Python中的列表推导式和生成器表达式 - 知乎
- Iterables vs. Iterators vs. Generators
- Python“列表推导式”和“生成器表达式”的区别小结_列表推导式和生成器的区别_努力的小黄呀的博客-CSDN博客