seansie's blog

python一行系簡潔程式碼技巧示範

Python 經常被譽為一種簡潔而優雅的程式語言。這種簡潔性並非偶然,而是 Python 從設計之初就堅持的理念。Python 提供了豐富的內建工具,讓我們能用精簡的程式碼完成各種任務。更令人驚嘆的是,許多功能甚至可以濃縮成一行程式碼,展現出 Python 獨特的魅力。

在本文中,我將分享一些我常用的「一行絕技」,希望能幫助你更深入地了解 Python 的簡潔之美,並為你的編碼帶來更多啟發。

清單推導式

有時候,我們需要對陣列中的每個元素進行相同的操作。尤其在 Python 這種動態類型語言中,從鍵盤讀取的整數數據會以字串形式儲存,這時如果要對這些資料進行數學運算,就不得不逐一使用 int() 函數將每個元素轉換成整數型態,就算有for迴圈,這個過程還是相當繁瑣

如果不用列表推導式,正常情況我們會用for迴圈,遍歷整個陣列

for i in range(len(arr)):
	arr[i]=int(arr[i])

稍微提醒一下,在 for i in ? 這種寫法中,i 實際上是 arr 中元素的副本,換句話說,修改 i不會影響到 arr 陣列中的元素。因此,如果想要修改所有元素的形態,我們必須藉助 range() 函數建立一個儲存arr所有元素的索引陣列,然後逐一存取 arr 中的元素,才能成功地進行修改。

雖然這種寫法已經算簡潔,但有些人會選擇建立一個新陣列,再逐一複製元素,這種做法顯然更加複雜。

相較之下,使用清單推導式,只需輸入 [int(i) for i in arr] 即可達成相同目的,效率顯著提升

格式

[表達式 for 變數 in 可迭代物件 ]

可迭代物件

  • 它是您希望對其每個元素進行操作的目標。

變數

  • 在每次迭代中,它會依序代表可迭代物件中的每一個元素。
  • 您可以把它想像成一個臨時的容器,用來裝載目前正在處理的元素。

運算式

  • 這是您定義的規則,用來決定如何轉換每個元素。
  • 運算式的結果會被收集起來,形成一個全新的列表。

最後,這個方括號的語法會回傳一個逐項依照表達式規則改寫的清單。

進階if-else用法

Python的列表生成式(List comprehension)提供了一個簡潔的方式來創建新的列表。在某些情況下,我們可能需要根據特定條件來過濾元素,這時就可以在列表生成式中加入if條件式。

範例

假設我們有一個列表 arr,其中包含了一些字串形式的數字,我們希望將其中的正整數轉換為整數物件。

[int(i) for i in arr if i>0]

在這個例子中,我們使用 if int(i) > 0 來確保只轉換那些代表正整數的字串。

如此一來就可以用相當簡潔的語法來實現複雜的運算邏輯了。

甚至可以在用else關鍵字來實現if-else一行解,如下所示。

順便做一下橫向類比,這個東西有點像是C++的三元運算子,其實這種結構在眾多程式語言都蠻常見的。

C++三元運算子

條件 ? 表達式1 : 表達式2

條件:一個會被判斷為 true 或 false 的布林表達式。

表達式1:如果條件是真的,就用這個表達式的值。

表達式2:如果條件是假的,就用這個表達式的值。

詳情可以參考本文文章(連結如下)

C++ 教學 三元運算子

匿名函數

雖然我們習慣將程式中重複的部分封裝成函數,但有時函數本身並沒有複雜的邏輯,只是單純地回傳一個由參數組成的表達式。例如,在洪水填充演算法(floodfill)中,用來判斷邊界條件的布林函數就是一個很好的例子。

def isvalid(x,y,xMax,yMax):
    return x>=0 and y>=0 and x<xMax and y<yMax

在不使用匿名函數的情況下,這已經是最簡潔的寫法了。有些人甚至會使用 if-elif-else 判斷式來逐一檢查條件!

然而,有了匿名函數,我們可以將其濃縮成一行程式碼,大幅提升效率和可讀性,讓程式更加優雅。

isvalid =lambda x,y,xMax,yMax:x>=0 and y>=0 and x<xMax and y<yMax

你看,這樣一行程式碼就搞定了,是不是既簡潔又強大?此外,當需要將函數作為參數傳遞時,匿名函數更能展現其簡潔的優勢!

格式

lambda x1,x2 ....xn:f(x1,x2.....xn) 
  • lambda關鍵字:告訴python這是匿名函數,使我們可以使用這個簡潔語法。
  • x1,x2.....xn:該函數的所有參數,參數間以逗點隔開
  • f(x) :該匿名函數索回傳的表達式,這裡以f(x1,x2...xn)表示。

連續動作示範

有時可以結合數種技巧來達成一行解的目標

functools.reduce()函數

基礎用法

例如求數個數字的最大公因數,常規作法是用for迴圈遍歷整個陣列,但是這個作法稍嫌繁瑣,畢竟不要重複發明輪子嘛!

def gcd_of_array(arr):
	` gcd = arr[0]
    for num in arr[1:]:
        while num:
            gcd, num = num, gcd % num
    return gcd

如果用reduce()函數的話,就可以用一個函數解決這種問題。

reduce(m.gcd(),arr)

其他好用的內建函數,的近期再更新。