Python:列表理解
Python 支持称为“列表推导”的概念。它可以用来以非常自然、简单的方式构建列表,就像数学家习惯做的那样。
以下是数学中描述列表(或集合、元组或向量)的常用方法。
S = {x² : x in {0 ... 9}}
V = (1, 2, 4, 8, ..., 2¹²)
M = {x | x in S and x even}
您可能从学校的数学课中知道上述内容。在 Python 中,您几乎可以像数学家一样编写这些表达式,而无需记住任何特殊的神秘语法。
这就是您在 Python 中执行上述操作的方式:
>>> S = [x**2 for x in range(10)]
>>> V = [2**i for i in range(13)]
>>> M = [x for x in S if x % 2 == 0]
>>>
>>> print S; print V; print M
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096]
[0, 4, 16, 36, 64]
我确定你想看一个更复杂的例子。 :-) 下面是另一种计算素数的方法。有趣的是,我们首先构建了一个非素数列表,使用单个列表推导,然后使用另一个列表推导得到列表的“逆”,即质数。
>>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
>>> primes = [x for x in range(2, 50) if x not in noprimes]
>>> print primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
注意:您可以将列表推导式嵌套在彼此之间,因此您可以使用单个语句编写上述示例(不需要临时变量“noprimes”)。但是,这样的行往往会变得很长且可读性较差,因此不建议这样做。
当然,列表推导不仅适用于数字。列表可以包含任何类型的元素,包括字符串、嵌套列表和函数。您甚至可以在一个列表中混合不同的类型。
以下处理字符串列表并生成列表列表。每个子列表包含两个字符串和一个整数。
>>> words = 'The quick brown fox jumps over the lazy dog'.split()
>>> print words
['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
>>>
>>> stuff = [[w.upper(), w.lower(), len(w)] for w in words]
>>> for i in stuff:
... print i
...
['THE', 'the', 3]
['QUICK', 'quick', 5]
['BROWN', 'brown', 5]
['FOX', 'fox', 3]
['JUMPS', 'jumps', 5]
['OVER', 'over', 4]
['THE', 'the', 3]
['LAZY', 'lazy', 4]
['DOG', 'dog', 3]
>>>
>>> stuff = map(lambda w: [w.upper(), w.lower(), len(w)], words)
>>> for i in stuff:
... print i
...
['THE', 'the', 3]
['QUICK', 'quick', 5]
['BROWN', 'brown', 5]
['FOX', 'fox', 3]
['JUMPS', 'jumps', 5]
['OVER', 'over', 4]
['THE', 'the', 3]
['LAZY', 'lazy', 4]
['DOG', 'dog', 3]
上面的例子也证明了你可以用 map() 和一个 lambda 函数做同样的事情。但是,在某些情况下,您不能使用 map() 而必须使用列表推导,反之亦然。当您可以同时使用这两种方法时,通常最好使用列表推导式,因为大多数情况下这样更有效且更易于阅读。
当构造规则过于复杂而无法用“for”和“if”语句表达时,或者构造规则可以在运行时动态更改时,您不能使用列表推导式。在这种情况下,您最好将 map() 和/或 filter() 与适当的函数一起使用。当然,您可以将其与列表推导结合使用。