python推导式是非常简洁高效的数据整合手段,功能强大且运行效率极高。本文将带你深入了解并掌握推导式,并将告诉你什么时候该用推导式什么时候不该用推导式。
变量名 = [ 表达式 for 变量 in 迭代器 [ if 判断条件]]
变量名:推导式是数据整合手段,推导式左边的变量名用来保存整合后的数据。
变量:这个变量是临时变量,用来指代迭代器中的元素。
表达式:推导式右边表达式部分,在表达式部分可以对变量——即对迭代器中的每个元素做处理。
迭代器:指生成推导式的数据源,迭代器可以是列表、元组、字典、集合、可迭代的对象。
判断条件:if 判断条件可以对变量——即对迭代器中的每个元素做判断,判断结果为True的保留,判断结果为False的舍弃。注意python的逻辑判断比较宽泛,结果为False、数字0、None、空字符串、空容器都判断为False,结果为True、任意数字、任意字符串、任意有元素的容器都判断为True。
推导式可以用来创建列表、字典、集合、迭代器。
创建列表
nums = [i for i in range(10)]
print(nums)
out:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
创建字典
nums = [i for i in range(10)]
letters = [j for j in "abcdefghij"]
nums = [i for i in range(10)]
letters = [j for j in "abcdefghij"]
my_dict = {j:i for j,i in zip(letters,nums)}
print(my_dict)
out:
{'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9}
创建集合
letters = [j for j in "abcdefghij"]
my_set = {i for i in letters}
print(my_set)
out:
{'h', 'i', 'd', 'f', 'j', 'a', 'g', 'b', 'c', 'e'}
创建迭代器
nums = (i for i in range(10))
print(nums)
out:
<generator object <genexpr> at 0x000002357DA4B350>
注意:迭代器的概念比较抽象,简单解释就是它是一个惰性取值的一次性容器。优点是非常节省内存,缺点是不够直观。在数据量超级大要考虑节省内存空间时请使用迭代器。(如果想要深入理解迭代器,可以关注我,查看我以前写的“python之彻底搞懂迭代、可迭代、迭代器的区别”系列文章)
经过上述2节的内容了解,接下来尝试通过各种案例来深入理解并掌握推导式:
筛选序列中的元素
nums= [1,3,5,-1,-2,0,8]
result1 = [i for i in nums if i>0]
result2 = [a for a in nums if a%2==0]
print(result1)
print(result2)
out:
[1, 3, 5, 8]
[-2, 0, 8]
处理字典中数据
shares = {'南钢股份':3.34,'攀钢钒钛':3.36,'马钢股份':3.5,'山东钢铁':3.55,'博汇纸业':3.59,'紫金矿业':3.6}
result = {key:shares[key] for key in shares if shares[key]>3.5}
print(result)
out:
{'山东钢铁': 3.55, '博汇纸业': 3.59, '紫金矿业': 3.6}
整合多维列表
a = [[[1,2,3],[4,5,6],[7,8,9]],[[10,11,12],[13,14,15],[16,17,18]],[[19,20,21],[22,23,24],[25,26,27]]]
b = [z for x in a for y in x for z in y]
print(b)
out:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27]
请对比下面2段代码,思考哪个好?
x = {'a':1,'b':2,'c':3}
y = {'b':5,'c':6,'d':7}
z = {key:x[key] for key in x.keys()&y.keys() }
print(z)
out:
{'c': 3, 'b': 2}
x = {'a':1,'b':2,'c':3}
y = {'b':5,'c':6,'d':7}
x_y = x.keys()&y.keys()
z = {key:x[key] for key in x_y }
print(z)
out:
{'c': 3, 'b': 2}
下面的代码将 x字典与y字典求交集的运算提前算好并赋值给临时变量x_y,然后再使用推导式生成z,就多写了这一行代码,运行效率会提高很多。因为推导式本质上是一种循环,记住一条原则:能在循环外面做的事一定要放在外面做。
请看案例,对table中键相同的数据累计值:
table = [{'a': 1}, {'a': 2}, {'b': 0}, {'b': 1}, {'c': 5}]
result = {i: j[i] for j in table for i in j}
print(result)
out:
{'a': 2, 'b': 1, 'c': 5}
在这个案例中使用推导式不能得出正确结果。
推导式只能在表达式部分对遍历的数据做相同运算,不能对遍历的数据做不同运算。所以当你的需求是遍历数据的同时要对不同的数据做不同的运算或类似上述案例中对不同的键分别做运算时不要用推导式。
记住推导式的特点:在表达式中对数据做相同运算。