Python 中連線兩個字串的方法有兩個: + 和 join()

當我開始使用 Python 的時候,通常會使用 + 這個運算子來連線字串,這個方法簡單又直接。

後來在看其他的人程式碼,他們卻喜歡使用 。join() 這個方法連線字串,下面我來說一說為什麼大家更傾向使用 。join(),而不是 +這個運算子。

開始

作為初學者,使用 + 運算子連線字串,程式碼很簡單:

str1 = “I love ”

str2 = “Python。”

print(str1 + str2)

# 輸出

# I love Python

當深入學習後,會發現其他人的程式碼更傾向於使用 join() 方法,像這樣:

str1 = “I love ”

str2 = “Python。”

print(‘ ’。join([str1, str2]))

# 輸出

# I love Python

說實在的,當我看見上面的程式碼,我覺得它很不直觀,而且還不好看。

連線多個字串

不過,這一次我們需要連線列表中的多個串。

strs = [‘Life’, ‘is’, ‘short,’, ‘I’, ‘use’, ‘Python’]

最初,我是這樣寫的:

strs = [‘Life’, ‘is’, ‘short,’, ‘I’, ‘use’, ‘Python’]

def join_strs(strs):

result = ‘’

for s in strs:

result += ‘ ’ + s

return result[1:] # 刪除前面的空格

join_strs(strs)

# 輸出

# Life is short, I use Python

在這個例子裡,我是用 for 迴圈一個一個的連線字串,最後我還要去除第一個字元前面的空格,因為迴圈裡每次連線的時候,都在前面加了一個空格。當然,也可以透過在 for 迴圈裡面加一個判斷,當 index = 0 的時候不加這個空格,不管怎樣,都要用 for 迴圈去做這些事情。

當我知道 。join() 這個方法的時候:

def jion_strs_better(strs):

‘ ’。join(strs)

jion_strs_better(strs)

# 同樣輸出

# Life is short, I use Python

是不很簡單,一行程式碼就解決了這個問題,而且不用考慮空格的問題。

不過,這個優點並不是放棄使用 + 運算子,轉向 join() 方法的原因。

join() 方法背後的邏輯

接下來我們比較一下這兩個方法的效能,可以使用 Jupyter Notebook 的魔法糖方法

%timeit

對這兩個方法進行評估。

Python 中儘量不要使用“+”來連線兩個字串

上面顯示的效能結果是透過十萬次的操作得出來的,所以結果顯而易見:

使用 join() 方法連線列表中的字串,比使用 + 運算子要快4倍。

為什麼會有這麼大差距呢?

下圖就是使用 + 運算子透過 for 迴圈連線字串的過程:

Python 中儘量不要使用“+”來連線兩個字串

透過 for 迴圈,找到每個字串。

Python 執行表示式

result += ' ' + s

並且為 空格申請記憶體地址(get memory for a white space)

然後執行程式意識到空格也需要與字串連線,因此它也將為字串申請記憶體地址,第一個迴圈為 Life (get memory for “life”)

對於每次迴圈,執行器都要申請兩次記憶體地址,一次為空格,一次為字串

總共需要12次的記憶體地址分配

我們再來看一下 join() 方法:

Python 中儘量不要使用“+”來連線兩個字串

執行器首先會計算列表裡有多少個字串,例子中是6個

這意味這連線列表裡面的字串需要重複 6-1=5次

所以執行器知道此次操作需要分配 11 個記憶體地址,這些會被預先應用和分配

然後按順序執行並返回結果

所以兩個方法的主要差別就是在記憶體地址分配次數上,這是這兩個方法效能差別的主要原因。

想象一下,使用 join()方法連線 6 個字串已經比 + 運算子快了4倍。如果要連線更多的字串呢,這種差別也會是更大。

總結

在這篇文章中,我們比較了 Python 連線兩個字串 + 運算子和 join() 的區別,從效能方面比較,join() 是首選。