原文链接: Python 递推式构造列表(List Comprehensions)
上一篇: 用scanf获取一行字符串包括空格的以及C语言函数
下一篇: 通信网络 ccf 深度优先搜索
你需要构造一个新的列表,列表中的元素是从一个已知列表中的元素计算而得到的.
比如你要创建一个列表,里面的元素是另一个列表中的元素加23后得到的.使用递推式构造列表是最理想的方法:
thenewlist = [x + 23 for x in theoldlist]
如果你希望用一个列表中大于5的元素构造一个新的列表,使用递推式也是很方便的:
thenewlist = [x for x in theoldlist if x > 5]
如果你希望将上面的两种情况组合起来,可以使用if表达式, 还可以使用计算式.比如给选中的元素加23,用一句话写成:
thenewlist = [x + 23 for x in theoldlist if x > 5]
优雅,清晰和实用,是Python的核心思想.递推式表现了3者的完美接合.的确,递推式是构造列表的最好方法,有时候,甚至也是修改列表的不错的选择.比如,你需要将列表中大于100的数改成100,可以这样写:
L[:] = [min(x,100) for x in L]
给列表的完整切片赋值会修改列表的内容,而不是仅仅重新绑定变量名,如果你写成L=...就是重新绑定变量名了.
如果你仅仅想对列表进行迭代,最好还是使用循环,而不是递推式,可以参考下一节.
如果有另外的内建方法可以完成同样的功能,最好也不要使用迭代式.比如复制列表 ,使用L1 = list(L),不要用:
L1 = [x for x in L]
另外,如果要对列表中的每一个元素进行函数操作,并将其返回值作为元素使用,请使用map函数,L1 = map(f,L),而不是[f(x) for x in L].不过在大多数情况下,使用递推式是比较方便的.
在Python2.4中,如果列表比较长,而且你一次只需要其中的一个元素, 使用生成表达式比较合适.生成表达式的写法和递推式是很类似的,它使用()来区分.在Python2.3中,比如我们要获得列表元素的和,而不是其中的每一个元素,可以这样写:
total = sum([x + 23 for x in theoldlist if x > 5])
在Python2.4中,可以不要[]:
total = sum(x + 23 for x in theoldlist if x > 5)
除了少写一对[],表达式也避免了维护一个列表,节省了内存空间.尤其当列表很长的时候,可以提高速度.
下面的递推式构造列表(list comprehension)创建了毕达哥拉斯三元组:
>>> [(x,y,z) for x in range(1,30) for y in range(x,30) for z in range(y,30) if x**2 + y**2 == z**2] [(3, 4, 5), (5, 12, 13), (6, 8, 10), (7, 24, 25), (8, 15, 17), (9, 12, 15), (10, 24, 26), (12, 16, 20), (15, 20, 25), (20, 21, 29)]
# 字典的深拷贝
import copy
dict = {"a" : "apple", "b" :{"g" : "grape", "o" : "orange"}}
dict2 = copy.deepcopy(dict)
dict3 = copy(dict)
dict2["b"]["g"] = "orange"
print (dict) # 不改变
dict3["b"]["g"] = "orange"
print (dict) # 改变
两个集合的交叉乘积:
>>> colours = [ "red", "green", "yellow", "blue" ] >>> things = [ "house", "car", "tree" ] >>> coloured_things = [ (x,y) for x in colours for y in things ] >>> print coloured_things [('red', 'house'), ('red', 'car'), ('red', 'tree'), ('green', 'house'), ('green', 'car'), ('green', 'tree'), ('yellow', 'house'), ('yellow', 'car'), ('yellow', 'tree'), ('blue', 'house'), ('blue', 'car'), ('blue', 'tree')] >>>
递推式构造生成器(generator comprehension)在Python2.6中被介绍过。它们是一个简单的用圆括号括起来的生成表达式,除此之外,它的语法和工作原来都很像递推式构造列表(List comprehension),但是递推式构造生成器(generator comprehension)返回的是一个生成器而不是一个列表。
>>> x = (x **2 for x in range(20)) >>> print(x) at 0xb7307aa4> >>> x = list(x) >>> print(x) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361]