Python趣味入門10:推倒繁瑣化煩為簡的推導式

dosboy發表於2023-12-29

前言

《西部世界》的德洛麗絲進入了MAZE迷宮,假設她需要列出一系列的平方數作為密碼,來進入迷宮。在以往的程式碼生成類似的數列需要使用迴圈語句,寫多行語句。Python有了推導式,只需要1句就足夠了,下面介紹本篇的主角。

本篇的主角是推導式comprehensions(又稱解析式),是Python的大殺器之一。推導式是可以從某組資料序列構建另一個組的資料序列的方式。 Python的每一種集合形式的資料結構,都對應有推導式,總共有3種形式:

  • 列表(list)推導式
  • 字典(dict)推導式
  • 集合(set)推導式

1、推導式的形式

下面推導式可以形成0至9當中偶數的平方數,即:[0,4,16,36,64],其中紅色的部分是每一個推導式必須不變的。

Python趣味入門10:推倒繁瑣化煩為簡的推導式

① 與結尾是成對的中括號[]表式 這是一個生成列表的推導式,我們可以使用{}來表示 字典和集合。當然如果是字典,②的部分就必須要有冒號:。

② 集合中元素的表示式。當前表示式表示生成的列表中的元素是變數的平方數,這部分的變數名稱必須在④部分出現。

③⑤ 紅色部分,for…in…表示迴圈,這是推導式必須的。③是定義的變數名稱,表示in後④的每一個元素。

④定義變數,表示⑥集合中的每一個元素。

⑥現成的集合變數,或是現有的集合元素。

⑦篩選條件:可以省略不寫,如上式條件為x%2==0,即意味著只有當x滿足偶數的情況下才會加入②部分的表示式運算並把結果加入集合 ,如果x不滿足這個條件那麼就跳過。我們在終端命令列中,輸入上述表示式,看看:

>>> [   x**2  for    x    in   range(10)   if x%2==0]
[0, 4, 16, 36, 64]
>>> 

2、生成器()

我們把最外的括號換成圓括號,就可以形成生成器generator,生成器不會立即計算結果,只在需要的時候生成結果,有利於最佳化運算節省記憶體。

如下的程式碼可以計算半徑1-10的圓面積,每一個元素包括一個關鍵字為關徑,值為面積的字典型別,如果使用生成器我們就要使用另一個for...in語句來呼叫它。

 

1 #生成器示例
2 gen = ({x:x**2* 3.14159} for x in range(1,10))
3 print(gen) #看看是不是有結果
4 for g in gen:
5     print(g)

 

執行的結果如下所示:

<generator object <genexpr> at 0x10e0c4200>
{1: 3.14159}
{2: 12.56636}
{3: 28.27431}
{4: 50.26544}
{5: 78.53975}
{6: 113.09724}
{7: 153.93791}
{8: 201.06176}
{9: 254.46878999999998}

如上所示第一行顯示不出任何結果,只是告訴您它是一個生成器物件。

3、推導式與互動使用

推導式本質上還是迴圈,它可以和任何語句搭配使用,在西部世界中,提洛公司Delos在每次“遊戲”結束後都要錄入5個清除記憶的host接待者的姓名,這個名單錄入功能使用了推導式之後,會非常簡單。

print(['%d.%s'%(x,input()) for x in range(1,6)])

  


這個語句執行只後,系統會等待您輸入5個姓名,並且加上序號列印出來,執行的結果如下:
Dolores
Bernard 
Maeve
Teddy
Grace
['1.Dolores', '2.Bernard', '3.Maeve', '4.Teddy', '5.Grace']

上面的Dolores,Bernard ,Maeve ,Teddy 和Grace五個人的姓名是鍵盤輸入進去的,最後一行是程式碼列印出來。

4、推導式的巢狀

既然說到神奇的推倒式,本篇繼續再推倒一個巢狀難題。

聽好了:如何1行語句列出2-100的質數?使用其它任何語言這是不可能的任務。

在解決這個問題之前,我們分2步走,先看看如何判斷一個質數,即沒有因子的數。

(1)我們先使用推導式把該數的因子列出來,假設這個數是M。如下的程式,就可以完成這個任務。

M=int(input())
print([ x for x in range(2,M) if M%x ==0])

  

我們試試看輸入100的結果是什麼?列出了所有100的因子。

[2, 4, 5, 10, 20, 25, 50]

(2)下面我們再把M擴充套件到2-100的迴圈,分析上一步的結果,其實是整個質數的判斷條件,如果M是質數那麼這個列表一定是空的。所以下面我們把上面的式子放在外迴圈的條件中就行了。

print([M for M in range(2,100) if not [ x for x in range(2,M) if M%x ==0] ])

  


執行之後的結果如下圖:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

推導式還有很多神奇的應用,就不一一列舉了。

緊跟小牛步的腳步,學習Python有趣不掉隊。

相關文章