1、 Pythonic - 很Python 寫一段代碼生成1到100之間的數字的平方的列表,答案是: 1, 4, 9, 16... 如果你這樣寫,你就不Pythonic了: 解釋 nums = [] for i in range(1, 101): nums.append(i*i) print(num ...
1、 Pythonic - 很Python
寫一段代碼生成1到100之間的數字的平方的列表,答案是:
1, 4, 9, 16...
如果你這樣寫,你就不Pythonic了:
解釋nums = [] for i in range(1, 101): nums.append(i*i) print(nums)
正確的寫法是使用Python的推導式:
nums = [i*i for i in range(1, 101)]
2、 帶條件的推導式
生成一個列表,包含1到100之間是3的倍數的數字的方法:
9, 36, 81...
代碼:
nums = [i * i for i in range(1, 101) if i % 3 == 0]
3、 帶條件的表達式
生成一個列表,如果是3的倍數就用平方,否則就用是數字本身:
1, 2, 9, 4, 5, 36...
代碼:
nums = [i * i if i % 3 == 0 else i for i in range(1, 101)]
結合上面的3個例子,來看一下推導式總結:
- 推導式從一個可枚舉數據(列表,元組,集合,字典等)推導出一個列表。也可以推導出生成器,集合或字典。
- 推導式可以加推導條件,只對符合條件的元素推導
- 要推導出的元素使用表達式生成,可以用if else生成不同元素
[表達式 if 表達式條件 else 分支 for i in 序列 if 推導條件]
4、 使用函數
如果推導條件或者表達式特別複雜怎麼辦?可以使用函數。
推導所有1-100之間的所有質數:2,3,5,7...
解釋def is_prime(num): if num == 1: return False for i in range(2, num): if (num % i) == 0: return False else: return True p_nums = [i for i in range(1, 100) if is_prime(i)] print(p_nums)
把推導的條件放在函數中,既可以應對複雜的條件,又可以利用推導式的簡潔寫法。
同理,如果生成推導結果的過程很複雜,也可以把邏輯放到函數中。
推導1900到2021年之間所有的年份,標記出閏年,生成結果:
1900, 1901, 1902, 1903, '閏1904'
代碼:
解釋def is_run(year): if (year % 4) == 0: if (year % 100) == 0: if (year % 400) == 0: return True # 整百年能被400整除的是閏年 else: return False else: return True # 非整百年能被4整除的為閏年 else: return False ryears = [f'閏{y}' if is_run(y) else y for y in range(1900, 2021)] print(ryears)
5、 嵌套表達式 - 不推薦使用
從2000年到2021年,生成每個月份:'2000年:1月', '2000年:2月', '2020年:3月', ..., '2021年:12月'
monthes = [f'{y}年:{m}月' for y in range(2000, 2022) for m in range(1,13) ]
這裡有兩個for迴圈,類似於:
解釋monthes = [] for y in range(2000, 2022): for m in range(1, 13): monthes.append(f'{y}年:{m}月')
是不是下麵的特別容易懂?所以兩層的迴圈不推薦使用推導式,哈哈。
那我為什麼還要講?你會碰到有人這麼寫,知道它的存在還是有點必要的。
6、 推導巨大的列表 - 不要這麼乾!
推導出1到100億之間的數字的平方,代碼如下:
nums = [i * i for i in range(1, 10000000000)]
但是這段代碼很可能會卡死你的電腦,除非你的電腦是超級電腦。因為它要在記憶體中做100億次計算,然後保存這100億個數字。
7、 使用生成器
這種情況下,我們應該使用推導生成器,用法很簡單:
- 把方括弧改成圓括弧就可以了
nums = (i * i for i in range(1, 10000000000))
print(nums)
print(next(nums))
print(next(nums))
print(next(nums))
列印出來是一個生成器:
解釋<generator object <genexpr> at 0x7fa0b422feb0>
1
4
9
這是一個生成器,它不會一次性生成100億個數字,只有調用next()的時候,它才會生成一個新的,返回給你。也就是說,同一個時間,只保存一個數字。
8、 推導字典
推導字典的方式和推導列表很相似,只不過:
- 使用大括弧
- 使用鍵值對
推導一個包含數字和數字平方組成的字典,結果是這樣的:
{1: 1, 2: 4, 3: 9, ..., 100: 10000}
代碼:
nums_dict = {n: n * n for n in range(1, 101)}
print(nums_dict)
反過來,平方在前面,數字在後面:
nums_dict = {n * n:n for n in range(1, 101)}
print(nums_dict)
給下麵的字典按照分數排序:
{'麥叔':59, '張三':87, 'FGA':78, '石石':100, '莫名':90}
排序結果:
{'石石': 100, '莫名': 90, '張三': 87, 'FGA': 78, '麥叔': 59}
代碼:
scores = {'麥叔': 59, '張三': 87, 'FGA': 78, '石石': 100, '莫名': 90}
sored_scores = {item[0]: item[1] for item in sorted(scores.items(), key=lambda item: item[1], reverse=True)}
print(sored_scores)
- 先把字典scores變成一個元組列表:scores.items()
- 用sorted函數給元組列表排序:sorted(scores.items(), key=lambda item:item[1], reverse=True)
- 排序過程用lambda指定使用元組的第二列排序:key=lambda item:item[1]。預設是是第一列。
- 指定倒著排序,也就是分數高的在前面:reverse=True
- 使用推導式,把排好序的元組列表,生成一個新的排好序的字典:{item[0]:item[1] for item in ... }
9 推導集合Set
推導集合的方式和列表是一樣的,區別在於:
- 使用大括弧,類似於推導字典,但它是單個元素,而不是鍵值對。
- 集合會自動過濾掉重覆的元素。
下麵的名字列表,去掉前後空格後去掉重覆的名字:
[ '麥叔', '張三', ' 麥叔 ', 'FGA ', '張小三', 'FGA', '石石',' 莫名','莫名' ]
推導結果:
{'石石', 'FGA', '張小三', '莫名', '張三', '麥叔'}
代碼:
names = [ '麥叔', '張三', ' 麥叔 ', 'FGA ', '張小三', 'FGA', '石石',' 莫名','莫名' ]
new_names = {n.strip() for n in names}
print(new_names)
頂
Top
收藏
關註
評論