官术网_书友最值得收藏!

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é)生成字符串片段。

主站蜘蛛池模板: 长武县| 普格县| 南阳市| 县级市| 泽州县| 慈利县| 来安县| 三穗县| 自治县| 北宁市| 南江县| 佛学| 任丘市| 麦盖提县| 新郑市| 五大连池市| 琼海市| 吉林省| 平顺县| 英超| 灵武市| 顺昌县| 六枝特区| 沧源| 赣州市| 自贡市| 崇阳县| 鄂托克前旗| 阿图什市| 安达市| 雷山县| 和田县| 大兴区| 嵊泗县| 阳新县| 银川市| 新晃| 太仓市| 石景山区| 都兰县| 巴楚县|