初识表达式:
优雅、清晰和务实是python的核心价值观,如果想通过操作和处理一个序列(或其他的可迭代对象)来创建一个新
的列表时可以使用列表解析(List comprehensions)和生成表达式,通过这两个操作,我们可以看到这三个观点是如何
在python中和谐统一起来的。
一、三元表达式:
#定义阶段 def my_max(x,y): #定义一个比较两个参数大小的函数 max = x if x > y else y #用三元表达式表示 print(max) #打印最大值 #调用阶段 my_max(1,2) #按位置传入参数x=1,y=2 ----------以下是输出结果----------- 2
二、列表表达式:
在需要改变列表而不是需要新建某列表时,可以使用列表解析。列表解析表达式为:
[expr for iter_var in iterable] [expr for iter_var in iterable if judging condition]
第一种语法:首先迭代iterable里所有内容,每一次迭代,都把iterable里相应内容放到iter_var中,再在表达式中应
用该iter_var的内容,最后用表达式的计算值生成一个列表。
第二种语法:加入了判断语句,只有满足条件的内容才把iterable里相应内容放到iter_var中,再在表达式中应用该
iter_var的内容,最后用表达式的计算值生成一个列表。
实例如下:
l=['egg%s' %i for i in range(8)] #没有判断条件的形式 print(l) l1=['egg%s' %i for i in range(8) if i > 4] #有判断条件的形式 print(l1) ----------以下是输出的结果------------ ['egg0', 'egg1', 'egg2', 'egg3', 'egg4', 'egg5', 'egg6', 'egg7'] #列表l的结果 ['egg5', 'egg6', 'egg7'] #列表l1的结果
以上例子不用列表表达式的话,代码如下:
l = [] #定义l为空列表 for i in range(8): l.append('egg%s'%i) #往空列表追加内容 print(l) #打印输出 -----------------------------输出结果------------------------------ ['egg0', 'egg1', 'egg2', 'egg3', 'egg4', 'egg5', 'egg6', 'egg7'] ----------------以下是有判断条件的----------------- l1 = [] #定义l为空列表 for i in range(8): if i > 4 : l1.append('egg%s'%i) #往空列表追加内容 print(l1) #打印输出 ------------输出结果------------ ['egg5', 'egg6', 'egg7']
下面来一段相对复杂的代码:
要求:将下面列表l和字符串s里的元素都一一搭配起来。
l = [1,2,3,4] s = "hello" l1 = [] -----------下面是没有判断条件的----------- for i in l : #循环列表l for j in s: #循环字符串s t = (i,j) #将得到的值赋值给t l1.append(t) #将t追加到空列表l1 print(l1) #打印输出 --------------------------------输出结果---------------------------------- [(1, 'h'), (1, 'e'), (1, 'l'), (1, 'l'), (1, 'o'), (2, 'h'), (2, 'e'), (2, 'l'), (2, 'l'), (2, 'o'), (3, 'h'), (3, 'e'), (3, 'l'), (3, 'l'), (3, 'o'), (4, 'h'), (4, 'e'), (4, 'l'), (4, 'l'), (4, 'o')] ---------------------------下面是有判断条件的------------------------------ for i in l : #循环列表l if i > 2 : #加上判断条件 for j in s: #循环字符串s t = (i,j) 将得到的值赋值给t l1.append(t) #将t追加到空列表l1 print(l1) #打印输出 -------------------输出结果------------------- [(3, 'h'), (3, 'e'), (3, 'l'), (3, 'l'), (3, 'o'), (4, 'h'), (4, 'e'), (4, 'l'), (4, 'l'), (4, 'o')]
下面用列表表达式来执行:
l = [1,2,3,4] s = "hello" l1 = [(i,j) for i in l for j in s] print(l1) --------------------------------输出结果-------------------------------- [(1, 'h'), (1, 'e'), (1, 'l'), (1, 'l'), (1, 'o'), (2, 'h'), (2, 'e'), (2, 'l'), (2, 'l'), (2, 'o'), (3, 'h'), (3, 'e'), (3, 'l'), (3, 'l'), (3, 'o'), (4, 'h'), (4, 'e'), (4, 'l'), (4, 'l'), (4, 'o')] -------------------------下面是有判断条件的------------------------------- l1 = [(i,j) for i in l if i > 2 for j in s] print(l1) ---------------------输出结果------------------------ [(3, 'h'), (3, 'e'), (3, 'l'), (3, 'l'), (3, 'o'), (4, 'h'), (4, 'e'), (4, 'l'), (4, 'l'), (4, 'o')]
三、生成器表达式:
在应用场景中当序列过长, 而每次只需要获取一个元素时,应当考虑使用生成器表达式而不是列表解析。生
成器表达式的语法和列表解析一样,只不过生成器表达式是被()括起来的,而不是[],如下:
[expr for iter_var in iterable] [expr for iter_var in iterable if judging condition]
语法同上面列表解析,此处略。
实例如下:
g = ("egg%s"%i for i in range(8) if i > 3) #有判断条件的生成器表达式 print(g) print(next(g)) #手动next1 print(next(g)) #手动next2 for i in g: #自动在g里使用next方法 print(i) #打印结果 --------------------------以下输出结果------------------------------ <generator object <genexpr> at 0x0000000002532D58> #生成器g的内存地址 egg4 #手动next1结果 egg5 #手动next1结果 egg6 #使用for循环的结果,因为迭代器是一次性的,so,会接着上面打印 egg7 #使用for循环的结果
说明:
1、当需要只是执行一个循环的时候尽量使用循环而不是列表解析,这样更符合python提倡的直观性。
2、当有内建的操作或者类型能够以更直接的方式实现的,不要使用列表解析。
3、当序列过长, 而每次只需要获取一个元素时,使用生成器表达式。
4、列表解析的性能相比要比map要好,实现相同功能的for循环效率最差(和列表解析相比差两倍)。
5、列表解析可以转换为 for循环或者使用map(其中可能会用到filter、lambda函数)表达式,但是列表解析更
为简单明了,后者会带来更复杂和深层的嵌套。