Python 推导式
因为这段时间一直在用python写脚本,所以阅读他人代码的时候经常会看到一些python特有的语法糖,按照公司前辈的意思,这些东西不需要花很多精力去记,差不多会用就行。
主要来自:https://www.cnblogs.com/cwp-bg/p/9041319.html
一、列表推导式
列表推导式即生成列表的推导式,写法简单而优雅,可以将多行代码融合成一行。主要的作用是将其他对象转换成列表或对原来的列表进行过滤。
列表推导式的代码效率是高于多行循环结构的,原因是将原本多行代码融合一行,解释加快。
比如:要生成一个1、2、3、4...平方的列表
常规写法:
res = [] for i in range(1,11): res.append(i**2) print(res)
使用列表推导式后:
res = [x ** 2 for x in range(1,11)] print(res)
当然,如果需要筛选结果,可以进行条件过滤
# 对列表过滤,返回true的才会保留到列表 ls = [1,2,4,6] ls1 = [x**2 for x in ls if x > 3] print(ls1) # 结果:[16, 36] # 多条件过滤
# 注意这里是先条件判断 ls = [1,2,4,6] ls1 = [x**2 if x > 2 else x**3 for x in ls] print(ls1) # 结果:[1, 8, 16, 36] # 多重循环 ls = [1,2,4,6] ls1 = [x**y if x > 2 else x**3 for x in ls for y in ls] print(ls1) # 结果:[1, 1, 1, 1, 8, 8, 8, 8, 4, 16, 256, 4096, 6, 36, 1296, 46656]
二、生成器推导式
https://www.cnblogs.com/wkfvawl/p/14931848.html#scroller-4
在之前的文章中已经讲过了生成器了,生成器最大的特点是边迭代边输出,在涉及到需要遍历列表而不是针对列表的某个值操作时,使用生成器代替列表可以减少内存的消耗。
ls = [1,2,4,6] ls1 = (x**2 for x in ls) print(ls1) 结果:<generator object <genexpr> at 0x0000021B21DED150> # 当然我们也可以这样 def gener(l): for x in l: yield x**2 # 只不过定义结构偏重型,当操作复杂的时候才采用 # 通过for..in取数据不需要处理StopIteration for i in ls1: pass # next()方法需要处理StopIteration while True: try: print(next(ls1)) except StopIteration: pass
生成器推导式 与 列表推导式对比,似乎很像?
[x*x for x in range(0,10)] #列表推导式,这里是中括号 #结果 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] (x*x for x in range(0,10)) #生成器, 这里是小括号 #结果 <generator object <genexpr> at 0x7f0b072e6140>
但仔细一看,一个直接返回了表达式的结果列表, 而另一个是一个对象,该对象包含了对表达式结果的计算引用, 通过循环可以直接输出。
当表达式的结果数量较少的时候, 使用列表推导式还好, 一旦数量级过大, 那么列表推导式就会占用很大的内存,而生成器并不是立即把结果写入内存, 而是保存的一种计算方式, 通过不断的获取, 可以获取到相应的位置的值,所以占用的内存仅仅是对计算对象的保存
三、字典推导式
字典推导式在一些需要列表或元组转化成字典的场合可以写出很优雅的代码。
# dict()可以接受类似列表推导式的写法,前提是ls至少是二维可迭代对象,否则报错 ls = [('name1','xiao'),('name2','wang')] dict_ls = dict(x for x in ls) print(dict_ls) # 结果:{'name1': 'xiao', 'name2': 'wang'} # 也可以针对zip使用 d = dict(zip([1,2],[3,4,])) print(d) # 结果 {1: 3, 2: 4} # 直接和列表推导式相似的写法 d = {x:y for x,y in enumerate(range(10))}
四、集合推导式
按照列表推导式类似的写法我们可以写集合推导式。
print(set(i for i in range(5))) print({i for i in range(5)}) print(frozenset(i for i in range(5))) # 结果 {0, 1, 2, 3, 4} {0, 1, 2, 3, 4} frozenset({0, 1, 2, 3, 4})
五、元组推导式
由于()这个类似列表推导式的形式被生成器占用了,所有元组推导式使用tuple()来进行。
ls = [('name1',['1','2']),('name2','wang')] dict_ls = tuple(x for x in ls) print(dict_ls) #结果:(('name1', ['1', '2']), ('name2', 'wang'))