問題
你想將幾個小的字符串合并為一個大的字符串
解決方案
如果你想要合并的字符串是在一個序列或者 iterable 中,那么最快的方式就是使用 join() 方法。比如:
1
2
3
4
5
6
7
8
|
>>> parts = [ 'Is' , 'Chicago' , 'Not' , 'Chicago?' ] >>> ' ' .join(parts) 'Is Chicago Not Chicago?' >>> ',' .join(parts) 'Is,Chicago,Not,Chicago?' >>> ''.join(parts) 'IsChicagoNotChicago?' >>> |
初看起來,這種語法看上去會比較怪,但是 join() 被指定為字符串的一個方法。這樣做的部分原因是你想去連接的對象可能來自各種不同的數據序列(比如列表,元組,字典,文件,集合或生成器等),如果在所有這些對象上都定義一個 join() 方法明顯是冗余的。因此你只需要指定你想要的分割字符串并調用他的 join() 方法去將文本片段組合起來。
如果你僅僅只是合并少數幾個字符串,使用加號(+)通常已經足夠了:
1
2
3
4
5
|
>>> a = 'Is Chicago' >>> b = 'Not Chicago?' >>> a + ' ' + b 'Is Chicago Not Chicago?' >>> |
加號(+)操作符在作為一些復雜字符串格式化的替代方案的時候通常也工作的很好,比如:
1
2
3
4
5
|
>>> print ( '{} {}' . format (a,b)) Is Chicago Not Chicago? >>> print (a + ' ' + b) Is Chicago Not Chicago? >>> |
如果你想在源碼中將兩個字面字符串合并起來,你只需要簡單的將它們放到一起,不需要用加號(+)。比如:
1
2
3
4
|
>>> a = 'Hello' 'World' >>> a 'HelloWorld' >>> |
討論
字符串合并可能看上去并不需要用一整節來討論。但是不應該小看這個問題,程序員通常在字符串格式化的時候因為選擇不當而給應用程序帶來嚴重性能損失。
最重要的需要引起注意的是,當我們使用加號(+)操作符去連接大量的字符串的時候是非常低效率的,因為加號連接會引起內存復制以及垃圾回收操作。特別的,你永遠都不應像下面這樣寫字符串連接代碼:
1
2
3
|
s = '' for p in parts: s + = p |
這種寫法會比使用 join() 方法運行的要慢一些,因為每一次執行+=操作的時候會創建一個新的字符串對象。你最好是先收集所有的字符串片段然后再將它們連接起來。
一個相對比較聰明的技巧是利用生成器表達式(參考1.19小節)轉換數據為字符串的同時合并字符串,比如:
1
2
3
4
|
>>> data = [ 'ACME' , 50 , 91.1 ] >>> ',' .join( str (d) for d in data) 'ACME,50,91.1' >>> |
同樣還得注意不必要的字符串連接操作。有時候程序員在沒有必要做連接操作的時候仍然多此一舉。比如在打印的時候:
1
2
3
|
print (a + ':' + b + ':' + c) # Ugly print ( ':' .join([a, b, c])) # Still ugly print (a, b, c, sep = ':' ) # Better |
當混合使用I/O操作和字符串連接操作的時候,有時候需要仔細研究你的程序。比如,考慮下面的兩端代碼片段:
1
2
3
4
5
6
|
# Version 1 (string concatenation) f.write(chunk1 + chunk2) # Version 2 (separate I/O operations) f.write(chunk1) f.write(chunk2) |
如果兩個字符串很小,那么第一個版本性能會更好些,因為I/O系統調用天生就慢。另外一方面,如果兩個字符串很大,那么第二個版本可能會更加高效,因為它避免了創建一個很大的臨時結果并且要復制大量的內存塊數據。還是那句話,有時候是需要根據你的應用程序特點來決定應該使用哪種方案。
最后談一下,如果你準備編寫構建大量小字符串的輸出代碼,你最好考慮下使用生成器函數,利用yield語句產生輸出片段。比如:
1
2
3
4
5
|
def sample(): yield 'Is' yield 'Chicago' yield 'Not' yield 'Chicago?' |
這種方法一個有趣的方面是它并沒有對輸出片段到底要怎樣組織做出假設。例如,你可以簡單的使用 join() 方法將這些片段合并起來:
1
|
text = ''.join(sample()) |
或者你也可以將字符串片段重定向到I/O:
1
2
|
for part in sample(): f.write(part) |
再或者你還可以寫出一些結合I/O操作的混合方案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def combine(source, maxsize): parts = [] size = 0 for part in source: parts.append(part) size + = len (part) if size > maxsize: yield ''.join(parts) parts = [] size = 0 yield ''.join(parts) # 結合文件操作 with open ( 'filename' , 'w' ) as f: for part in combine(sample(), 32768 ): f.write(part) |
這里的關鍵點在于原始的生成器函數并不需要知道使用細節,它只負責生成字符串片段就行了。
以上就是Python 合并拼接字符串的方法的詳細內容,更多關于Python 合并拼接字符串的資料請關注服務器之家其它相關文章!
原文鏈接:https://www.kancloud.cn/kancloud/python3-cookbook/47169