列表推導式是Python最受喜好的特性之一。它容許用戶方便的從一個集合過濾元素,造成列表,在傳遞參數的過程當中還能夠修改元素。形式以下:python
[expr for val in collection if condition]
它等同於下面的for循環;app
result = [] for val in collection: if condition: result.append(expr)
filter條件能夠被忽略,只留下表達式就行。例如,給定一個字符串列表,咱們能夠過濾出長度在2及如下的字符串,並將其轉換成大寫:函數
In [154]: strings = ['a', 'as', 'bat', 'car', 'dove', 'python'] In [155]: [x.upper() for x in strings if len(x) > 2] Out[155]: ['BAT', 'CAR', 'DOVE', 'PYTHON']
用類似的方法,還能夠推導集合和字典。字典的推導式以下所示:spa
dict_comp = {key-expr : value-expr for value in collection if condition}
集合的推導式與列表很像,只不過用的是尖括號:rest
set_comp = {expr for value in collection if condition}
與列表推導式相似,集合與字典的推導也很方便,並且使代碼的讀寫都很容易。來看前面的字符串列表。假如咱們只想要字符串的長度,用集合推導式的方法很是方便:code
In [156]: unique_lengths = {len(x) for x in strings} In [157]: unique_lengths Out[157]: {1, 2, 3, 4, 6}
map
函數能夠進一步簡化:字符串
In [158]: set(map(len, strings)) Out[158]: {1, 2, 3, 4, 6}
做爲一個字典推導式的例子,咱們能夠建立一個字符串的查找映射表以肯定它在列表中的位置:string
In [159]: loc_mapping = {val : index for index, val in enumerate(strings)} In [160]: loc_mapping Out[160]: {'a': 0, 'as': 1, 'bat': 2, 'car': 3, 'dove': 4, 'python': 5}
假設咱們有一個包含列表的列表,包含了一些英文名和西班牙名:it
In [161]: all_data = [['John', 'Emily', 'Michael', 'Mary', 'Steven'], .....: ['Maria', 'Juan', 'Javier', 'Natalia', 'Pilar']]
你多是從一些文件獲得的這些名字,而後想按照語言進行分類。如今假設咱們想用一個列表包含全部的名字,這些名字中包含兩個或更多的e。能夠用for循環來作:io
names_of_interest = [] for names in all_data: enough_es = [name for name in names if name.count('e') >= 2] names_of_interest.extend(enough_es)
能夠用嵌套列表推導式的方法,將這些寫在一塊兒,以下所示:
In [162]: result = [name for names in all_data for name in names .....: if name.count('e') >= 2] In [163]: result Out[163]: ['Steven']
嵌套列表推導式看起來有些複雜。列表推導式的for部分是根據嵌套的順序,過濾條件仍是放在最後。下面是另外一個例子,咱們將一個整數元組的列表扁平化成了一個整數列表:
In [164]: some_tuples = [(1, 2, 3), (4, 5, 6), (7, 8, 9)] In [165]: flattened = [x for tup in some_tuples for x in tup] In [166]: flattened Out[166]: [1, 2, 3, 4, 5, 6, 7, 8, 9]
記住,for表達式的順序是與嵌套for循環的順序同樣(而不是列表推導式的順序):
flattened = [] for tup in some_tuples: for x in tup: flattened.append(x)
你能夠有任意多級別的嵌套,可是若是你有兩三個以上的嵌套,你就應該考慮下代碼可讀性的問題了。分辨列表推導式的列表推導式中的語法也是很重要的:
In [167]: [[x for x in tup] for tup in some_tuples] Out[167]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
這段代碼產生了一個列表的列表,而不是扁平化的只包含元素的列表。