列表推导式,也叫列表生成式,是一种方便生成列表的语句。
比如我们要将一个全是整数的列表中每个数取平方后放入新的列表,我们会这么写:
li = [3, 6, 9, 11]
# 定义一个空列表用来存储结果
news = []
# 将li中的元素挨个运算再添到结果列表
for i in li:
news.append(i*i)
print(news)
当然如果你会运用 map() 函数,也可以使用 map 来实现,不过这不属于我们讨论的范围。
那么通过列表推导式如何来生成这样一个包含原列表中每个元素的平方结果的新列表呢?
result = [i*i for i in li]
print(result)
这就是关键了:[i*i for i in li]
,分解一下:
- 外面的
[]
,声明这最终结果会是一个列表 -
i*i
,这个表达式是要放入列表中的元素 -
for i in li
,遍历 li,与普通 for 循环一样,只是从原来的站姿变成了横躺
这是一颗语法糖,通过列表推导式,可以有效减少代码。
再来看看,如果循环中有逻辑判断的情况:
比如,我们要提取 100以内能整除 7 的数并且放入列表。
# 先定义一个空列表,用来存储结果
seven = []
# 循环从 100 中进行对比
for i in range(100):
if i % 7 == 0:
seven.append(i)
print(seven)
列表推导式的效果如下:
result = [i for i in range(100) if i%7==0]
print(result)
还是那句话,是不是原来是竖排的代码变成了横躺。
那多重循环呢?
比如我们要从一个二维列表[[1,2,3], [4,5,6], [7,8,9]]
提取所有的偶数放入新的列表:
li = [[1,2,3], [4,5,6], [7,8,9]]
even = []
for i in li:
for j in i:
if j % 2 == 0:
even.append(j)
print(even)
换成列表推导式就是这样的:
result = [j for i in li for j in i if j%2==0]
print(result)
## [2, 4, 6, 8]
外层 for 循环写在前面,内层的 for 循环写在后面,最前面依然是你要加到列表中的表达式。
那如果我们想保留原来二维列表的样子,只是二维列表中只包含偶数。这就涉及到了推导式的嵌套:
result = [[j for j in i if j%2==0] for i in li]
print(result)
## [[2], [4, 6], [8]]
除了列表推导式以外,还有集合推导式,字典推导式,元组没有(元组推导式的写法是生成器)。
集合推导式:
写法上与列表推导式类似,只是最终生成的是集合,集合的特性是去重。
比如以下案例,从列表 [1,2,3,2,5,4,3,4]
中提取所有的不重复的偶数:
li = [1,2,3,2,5,4,3,4]
even = {i for i in li if i%2==0}
print(even)
## {2, 4}
字典推导式:
字典推导式的写法和集合推导式有点像,毕竟都是用大括号的。
先看一个例子,我们打算生成一个字典,把abc
中单个字符作为 key,把列表[1,2,3]
中每个元素作为 value:
l1 = 'abc'
l2 = [1, 2, 3]
result = {i:j for i in l1 for j in l2}
print(result)
字典推导式的写法是{key:value for i in seq}
,也就是说放入字典的每个元素都是键值对的形式。
刚开始应用推导式的时候,容易被写法搞晕,多写写就能熟练运用了。