python高级编程之列表推导式
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
python⾼级编程之列表推导式
1. ⼀个简单的例⼦
在Python中,如果我们想修改列表中所有元素的值,可以使⽤ for 循环语句来实现。
例如,将⼀个列表中的每个元素都替换为它的平⽅:
>>> L = [1, 2, 3, 4, 5]
>>> for i in range(len(L)):
... L[i] = L[i] ** 2
>>> L
[1, 4, 9, 16, 25]
另⼀种优雅的实现⽅式就是使⽤列表推导式(List Comprehensions):
>>> L = [1, 2, 3, 4, 5]
>>> L = [x ** 2 for x in L]
>>> L
[1, 4, 9, 16, 25]
2. 基本语法
我们具体来分析上⾯给出的例⼦
>>> L = [x ** 2 for x in L]
我们将列表推导式写在⼀个⽅括号内,因为它最终构建的是⼀个列表。
列表推导式主要由两部分构成:
循环变量表达式( x ** 2)
for 循环头部( for x in L )
是不是⾮常简单!
3. ⼯作原理
Python在执⾏列表推导式时,会对可迭代对象 L 进⾏迭代,将每⼀次迭代的值赋给循环变量 x ,然后收集变量表达式 x ** 2 的计算结果,最终由这些结果构成了新的列表,也就是列表推导式所返回的值。
只要⽀持 for 循环进⾏迭代的对象,都可以对它使⽤列表推导式。
例如,我们将⼀个字符串进⾏移位处理:
>>> S = 'abcde'
>>> S = ''.join([chr(ord(c)+1) for c in S])
>>> S
'bcdef'
4. ⾼级语法
除了像上⾯介绍的 [x ** 2 for x in L] 这种基本语法之外,列表推导式还有⼀些⾼级的扩展。
4.1. 带有if语句
我们可以在 for 语句后⾯跟上⼀个 if 判断语句,⽤于过滤掉那些不满⾜条件的结果项。
例如,我想去除列表中所有的偶数项,保留奇数项,可以这么写:
>>> L = [1, 2, 3, 4, 5, 6]
>>> L = [x for x in L if x % 2 != 0]
>>> L
[1, 3, 5]
4.2. 带有for嵌套
在复杂⼀点的列表推导式中,可以嵌套有多个 for 语句。
按照从左⾄右的顺序,分别是外层循环到内层循环。
例如:
>>> [x + y for x in 'ab' for y in 'jk']
['aj', 'ak', 'bj', 'bk']
4.3. 既有if语句⼜有for嵌套
列表推导式可以带任意数量的嵌套 for 循环,并且每⼀个 for 循环后⾯都有可选的 if 语句。
通⽤语法:
[ expression for x in X [if condition]
for y in Y [if condition]
...
for n in N [if condition] ]
例如,下⾯的代码输出了0~4之间的偶数和奇数的组合。
>>> [(x, y) for x in range(5) if x % 2 == 0 for y in range(5) if y % 2 == 1]
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]
等价于下⾯的⼀般 for 循环:
>>> L = []
>>> for x in range(5):
... if x % 2 == 0:
... for y in range(5):
... if y % 2 == 1:
... L.append((x, y))
>>> L
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]
4.4. 列表推导式⽣成矩阵
⽣成矩阵的⽅式有多种,例如⼿动赋值、⼀般for循环,还有就是列表推导式。
如果我们要⽤列表推导式⽣成下⾯的矩阵,可以怎么写?
>>> M = [[1, 2, 3],
... [4, 5, 6],
... [7, 8, 9]]
⼀种⽅法是:
>>> M = [[x, x+1, x+2] for x in [1, 4, 7]]
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
矩阵的列数少时可以使⽤这种⽅法。
如果矩阵的列数较多,我们可以使⽤另外⼀种⽅式:在循环变量的表达式中使⽤列表推导式。
具体代码如下:
>>> M = [[y for y in range(x, x+3)] for x in [1, 4, 7]]
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
与之前带 for 嵌套的语法不同,这个例⼦中,实际使⽤的是最基本的 [expression for x in L] 语法,只有⼀个 for 语句。
复杂的地⽅在于前⾯的变量表达式 expression 不再是简单的变量运算,⽽是⼀个列表推导式,在这个例⼦中就是 [y for y in range(x, x+3)] 。
内层的列表推导式返回⼀个⾏向量,⽽这些⾏向量经由外层的列表推导式,最终形成⼀个⼆维列表,也就是我们想要的矩阵。
当然,在实际的应⽤中不能单纯追求代码的简洁,还要考虑到代码的可读性和维护成本。
如果代码变得过于复杂,不易于理解,我们宁可多写⼏⾏代码来增加它的可读性。
5. ⽣成器表达式
⽣成器表达式与列表推导式的语法相同,区别在于⽣成器表达式的外⾯使⽤圆括号,⽽列表推导式使⽤⽅括号。
有关⽣成器的介绍,请参考这篇⽂章:
6. 集合推导式和字典推导式
注意:集合推导式和字典推导式只有在Python2.7以及之后的版本中才有,Python2.7之前的版本不⽀持这两种推导式。
集合推导式的语法与列表推导式相同,只需要把外⾯的⽅括号改成花括号即可。
例如,我们可以通过以下⽅式来⽣成⼀个集合:
>>> {x ** 2 for x in [1, 2, 2]}
{1, 4}
字典推导式的外⾯也是使⽤花括号,不过花括号的内部需要包含键值两部分。
在值不重复的情况下,我们可以通过字典推导式快速交换键值对:
>>> D = {'a':1, 'b':2, 'c':3}
>>> D = {value: key for key, value in D.items()}
>>> D
{1: 'a', 2: 'b', 3: 'c'}
总结:在编写或是阅读这类推导式的时候,⼀定要注意先从for..in开始,最后再看前⾯的循环变量表达式。