Python 中儘量不要使用“+”來連線兩個字串
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
對這兩個方法進行評估。
上面顯示的效能結果是透過十萬次的操作得出來的,所以結果顯而易見:
使用 join() 方法連線列表中的字串,比使用 + 運算子要快4倍。
為什麼會有這麼大差距呢?
下圖就是使用 + 運算子透過 for 迴圈連線字串的過程:
透過 for 迴圈,找到每個字串。
Python 執行表示式
result += ' ' + s
並且為 空格申請記憶體地址(get memory for a white space)
然後執行程式意識到空格也需要與字串連線,因此它也將為字串申請記憶體地址,第一個迴圈為 Life (get memory for “life”)
對於每次迴圈,執行器都要申請兩次記憶體地址,一次為空格,一次為字串
總共需要12次的記憶體地址分配
我們再來看一下 join() 方法:
執行器首先會計算列表裡有多少個字串,例子中是6個
這意味這連線列表裡面的字串需要重複 6-1=5次
所以執行器知道此次操作需要分配 11 個記憶體地址,這些會被預先應用和分配
然後按順序執行並返回結果
所以兩個方法的主要差別就是在記憶體地址分配次數上,這是這兩個方法效能差別的主要原因。
想象一下,使用 join()方法連線 6 個字串已經比 + 運算子快了4倍。如果要連線更多的字串呢,這種差別也會是更大。
總結
在這篇文章中,我們比較了 Python 連線兩個字串 + 運算子和 join() 的區別,從效能方面比較,join() 是首選。