什么是Python的推导式
Python里面有个很棒的语法糖(syntactic sugar),它就是 list comprehension
,有人把它翻译成“列表推导式”,也有人翻译成“列表解析式”。名字听上去很难理解,但是看它的语法就很清晰了。虽然名字叫做 list comprehension,但是这个语法同样适用于dict、set等这一系列可迭代(iterable)数据结构。
直接一点的解释就是:推导式是可以从一个数据序列构建另一个新的数据序列。
语法规范:
out_list = [out_express for out_express in input_list if out_express_condition]
其中的 if
条件判断根据需要可有可无。
为什么要用推导式
我们先看看下面的例子:
如果我想要得到个序列(可以是列表也可以是元组),可使用循环语句来完成。
比方我们要生成一个包含10以内的偶数的list:
evens = []
for i in range(10):
if i % 2 == 0:
evens.append(i)
但如果使用推导式(由于生成的列表,所以也叫做列表推导式),就只需要 一行代码就能完成。
evens = [i for i in range(10) if i % 2 == 0]
这里我们进行一下上面推导式的解释:
i
是我们每次循环时返回的值。
for i in range(10)
是的循环语句,其中的i也是我们需要每次在列表中元素生成的值
if i % 2 == 0
但由于我们不是所有i都需要,所以我们在其中加入判断,只有当判断为真是才会返回该i的值。如果我们不写这个判断。那就是所有i都为真,也就是所有i都会加到到列表中的元素中去。
再看看以下例子:
需要筛选出列表中所有大于0的值 :
nums = [1, 34, -23, -2, 23, 3, 52, 0 , -43]
res = [i for i in nums if i>0]
这里就很简单的就能完成了我们需要的功能了。
复杂的推导式
把一个矩阵(以列表为元素的列表)展平为一个列表。首先,我们用for
循环来实现一下:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
flattened = []
for row in matrix:
for i in row:
flattened.append(i)
如果写在推导式:
flattened = [i for row in matrix for i in row]
当然由于上面的推导式相当于是两个循环进行嵌套所以直接看会比较复杂。我们可以写成这样:
flattened = [
i # 最终放入列表中的元素是i,也就是第二个循环里的值。并不是第一个循环里的值
for row in matrix
for i in row
]
这种写法更加的官方。
有时候不应该强行使用推导式
“我们很容易犯的一个错误是,手上拿着一个锤子,看啥都认为是钉子,更何况拿着的是一个雷神之锤。”
看着推导式很简洁,明白了它的意思后觉得很简单。但我们也不要乱用,因为真的特别复杂的生成列表方法时强行使用推导式会让本来就复杂的生成方法变得更加让摸不着头脑。
练习
练习1:现在有一列表 lst = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] ,求出 1/4/7 和 1/5/9元素,思考如何取出
m1 = [row[0] for row in matrix] #求出 1/4/7
print(m1)
m2 = [matrix[index][index] for index in range(len(matrix))] #求出1/5/9
print(m2)
字典(dict)和集合(set)的推导式:
前面我们也提到过,推导式不仅仅适用于列表,它同样使用于字典dict和集合set。其中zip()
函数是用于把多个列表进行打包成一个迭代数据。
name = ["张三", "李四", "王五", "李六"] # 保存名字列表
sign = ["白羊座", "双鱼座", "狮子座", "处女座"] #保存星座列表
# 普通循环完成
d1 = {}
for i in range(len(name)):
d1[name[i]] = sign[i]
print(d1)
# 使用字典推导式完成
d2 = {v:k for k, v in zip(name, sign)}
print(d2)
把一个字典的key和value互换:
changed = {value: key for key, value in input_dict.items()}
以这个数据为准。把key与value进行互换:
"""
{'张三': '白羊座', '李四': '双鱼座', '王五': '狮子座', '李六': '处女座'}
以这个数据为准。把key与value进行互换
"""
d3 = {d1[key]:key for key in d1}
print(d3)
把两个列表组成一个字典:
name = ["张三", "李四", "王五", "李六"] # 保存名字列表
sign = ["白羊座", "双鱼座", "狮子座", "处女座"] #保存星座列表
dict1 = {i : j for i, j in zip(name, sign)} # 字典推导式
print(dict1)
集合
集合(set)是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。集合对象还支持 union(联合),intersection(交),difference(差)和 sysmmetric difference(对称差集)等数学运算。
注:一般用来除去重复数据
# 创建集合
s=set() #空集合
s1=set([]) #列表
s2=set(()) #元组
s3=set({}) #字典
#创建非空集合
s1=set([1,2,3,4])
#{1, 2, 3, 4}
s3=set({'a':2,'b':3,'c':4})
#{'c', 'a', 'b'}
集合添加的操作:
# add()方法
s=set('one')
#{'e', 'o', 'n'}
s.add('two')
#{'e', 'two', 'o', 'n'}
# update()方法
s=set('one')
#{'e', 'o', 'n'}
s.update('two')
#{'e', 'n', 't', 'w', 'o'}
集合删除操作:
setVar.remove(element)
集合的删除操作使用的方法跟列表是一样的,使用的也是remove方法。
setVar :为一个set类型的变量
element :表示要查找并删除的元素
s=set('one')
#{'e', 'o', 'n'}
s.remove('e')
#{'n', 'o'}
其它的set函数可以手册上进行查看。
集合推导式
基本与其它推导式差不多。例子:
set1 = {i**2 for i in range(1,4)} #i的平方:i**2
print(set1)
list1 = [1, 1, 2]
set2 = {i**2 for i in list1}
print(set2)