- Python進(jìn)階編程:編寫更高效、優(yōu)雅的Python代碼
- 劉宇宙 謝東 劉艷
- 1068字
- 2021-04-30 12:39:38
2.2.5 字符串拼接
在實(shí)際應(yīng)用中,我們經(jīng)常需要將多個字符串合并為一個字符串。不同的字符串合并方式對執(zhí)行效率的影響不同。
如果要合并的字符串是在一個序列或者迭代器中,那么最快的方式是使用join()方法,示例如下:
test_list = ['Life', 'is', 'short', 'Use', 'python'] print(' '.join(test_list)) print(','.join(test_list))
join()方法用于將序列中的元素以指定的字符連接生成一個新的字符串。這樣做的原因是連接的對象可能來自不同的數(shù)據(jù)序列(比如列表、元組、字典、文件、集合或生成器等),如果在所有對象上都定義一個join()方法明顯是冗余的,因此只需要指定想要的分割字符串并調(diào)用join()方法將文本片段組合起來即可。
如果只是合并少數(shù)字符串,使用加號(+)即可,代碼示例如下:
a_str = 'Life is short' b_str = 'Use python' print(a_str + ',' + b_str)
加號(+)操作符在做一些復(fù)雜字符串格式化的時候也很有用。
如果想在代碼中將兩個字面字符串合并起來,只需要簡單地將它們放到一起,不需要用加號(+)。
字符串合并可能看上去比較簡單,但是這個問題不能輕視,程序員經(jīng)常因?yàn)檫x擇不當(dāng)?shù)淖址袷交绞剑瑢?dǎo)致應(yīng)用程序性能嚴(yán)重降低。
注意:使用加號(+)操作符去連接大量的字符串,是非常低效的。因?yàn)榧犹枺?)連接會引起內(nèi)存復(fù)制以及垃圾回收操作。特別注意的是,永遠(yuǎn)不要像下面這樣寫字符串連接代碼:
str_val = '' for test_str in test_list: str_val += test_str
這種寫法比使用join()方法運(yùn)行得要慢一些,每次執(zhí)行“+=”操作會創(chuàng)建一個新的字符串對象。最好是先收集所有的字符串片段,然后再將它們連接起來。
一個相對較好的做法是在利用生成器表達(dá)式將數(shù)據(jù)轉(zhuǎn)換為字符串的同時合并字符串,代碼示例如下:
data_list = ['python', 23, 2020.4] print(','.join(str(d) for d in data_list))
避免不必要的字符串連接操作,代碼示例如下:
c_str = 'Let together' # not support print(a_str + ':' + b_str + ':' + c_str) # not support print(':'.join([a_str, b_str, c_str])) # support,is better print(a_str, b_str, c_str, sep=':')
當(dāng)混合使用I/O操作和字符串連接操作的時候,有時候需要仔細(xì)研究程序。相關(guān)代碼(merge_str.py)片段如下:
# Version 1 (string concatenation) f.write(chunk1 + chunk2) # Version 2 (separate I/O operations) f.write(chunk1) f.write(chunk2)
如果兩個字符串很小,版本1性能會更好些,因?yàn)镮/O系統(tǒng)調(diào)用天生就慢。如果兩個字符串很大,版本2會更加高效,因?yàn)樗苊饬藙?chuàng)建一個很大的臨時對象及復(fù)制大量的內(nèi)存塊數(shù)據(jù)。具體的選擇需要根據(jù)應(yīng)用程序特點(diǎn)來決定。
如果準(zhǔn)備編寫大量小字符串輸出的代碼,最好選擇使用生成器函數(shù)。利用yield語句產(chǎn)生輸出片段,代碼示例如下:
def sample_func(): yield 'Life' yield 'is' yield 'short' yield 'Use' yield 'python'
這種方法有趣的一面是,它并沒有對輸出片段到底要怎樣組織做出假設(shè)。我們可以簡單地使用join()方法將這些片段拼接起來,或者將字符串片段重定向到I/O,代碼示例如下:
text_val = ''.join(sample_func()) for str_val in sample_func(): f.write(str_val)
還可以寫出一些結(jié)合I/O操作的混合方案:
def combine_obj(source, max_size): str_list = [] size = 0 for item_val in source: str_list.append(item_val) size += len(item_val) if size > max_size: yield ''.join(str_list) str_list = [] size = 0 yield ''.join(str_list) with open('file_name', 'w') as f: for str_val in combine_obj(sample_func(), 8192): f.write(str_val)
原始的生成器函數(shù)不需要知道使用細(xì)節(jié),只需要負(fù)責(zé)生成字符串片段。
- 數(shù)據(jù)庫程序員面試筆試真題與解析
- TypeScript Blueprints
- Photoshop智能手機(jī)APP UI設(shè)計(jì)之道
- Mastering Concurrency in Go
- Spring Boot+Spring Cloud+Vue+Element項(xiàng)目實(shí)戰(zhàn):手把手教你開發(fā)權(quán)限管理系統(tǒng)
- C語言程序設(shè)計(jì)立體化案例教程
- Learning Data Mining with R
- 深度學(xué)習(xí)原理與PyTorch實(shí)戰(zhàn)(第2版)
- 數(shù)據(jù)分析與挖掘算法:Python實(shí)戰(zhàn)
- Web開發(fā)的平民英雄:PHP+MySQL
- AngularJS UI Development
- ArcPy and ArcGIS(Second Edition)
- Kohana 3.0 Beginner's Guide
- 跟小樓老師學(xué)用Axure RP 9:玩轉(zhuǎn)產(chǎn)品原型設(shè)計(jì)
- 軟件測試項(xiàng)目實(shí)戰(zhàn)之功能測試篇