python - 字符串连接性能

标签 python string-concatenation

现在我使用一个列表来存储更改后的字符串并使用 .join() 返回一个字符串

def applyCoder(text, coder):
    l = []
    for i in text:
        if i in coder:
            l.append(coder[i])
        else:
            l.append(i)
    return ''.join(l)

# example output, shifts all letters by 3 in a string
# print applyCoder("Hello, world!", buildCoder(3))
# buildCoder(3) returns dictionary, e.g. {'A': 'D', ...}
# >>> Khoor, zruog!

是否有更快的方法来更改和返回字符串?

最佳答案

这应该尽可能快:

''.join([coder[i] if i in coder else i for i in text])

与承受巨大开销的 for 循环相比,Python 中的列表推导式更加优化。我在 ''.join 中传递了列表理解而不是生成器,因为它必须在加入之前提前知道输入的长度。如果你给它一个生成器,它无论如何都必须将其放入列表中(这有点慢)。

实际上您可以进一步简化,应该更快 (由于方法调用,这实际上比上面的方法执行得慢)

''.join([coder.get(i,i) for i in text])

时间安排:

def applyCoder(text, coder):
    L = []
    for i in text:
        if i in coder:
            L.append(coder[i])
        else:
            L.append(i)
    return ''.join(L)

def list_comp(text, coder):
    return ''.join([coder[i] if i in coder else i for i in text])

def list_comp2(text, coder):
    return ''.join([coder.get(i,i) for i in text])

from timeit import timeit
from string import ascii_letters
d = dict(zip(ascii_letters, ascii_letters[3:] + ascii_letters[-3:]))


print timeit(stmt='applyCoder("Hello, world!", d)',
             setup='from __main__ import applyCoder, d;')

print timeit(stmt='list_comp("Hello, world!", d)',
             setup='from __main__ import list_comp, d;')    

print timeit(stmt='list_comp2("Hello, world!", d)',
             setup='from __main__ import list_comp2, d;')

print timeit(stmt='applyCoder("Hello, world!"*10, d)',
             setup='from __main__ import applyCoder, d;')

print timeit(stmt='list_comp("Hello, world!"*10, d)',
             setup='from __main__ import list_comp, d;')


print timeit(stmt='list_comp2("Hello, world!"*10, d)',
             setup='from __main__ import list_comp2, d;')

结果:

''' Test 1 '''
5.0159105417    # applyCoder
3.41502481461   # listcomp1
4.76796932292   # listcomp2

''' Test 2 '''
34.9718502631   # applyCoder
22.0451702661   # listcomp1
34.1682597928   # listcomp2

看来对 coder.get 的方法调用完全否定了列表理解的优点。因此,我确实预测它可能会比 listcomp1 慢,但我认为它不会产生这么大的影响。无论如何,列表理解仍然获胜。

更新: 如果您像这样修改 list_comp2:

def list_comp2(text, coder):
    coder_get = coder.get
    return ''.join([coder_get(i,i) for i in text])

时代在进步:

来自 4.76796932292(第一次测试)-> 3.95217394948

34.1682597928(第二次测试)->27.1162974624

关于python - 字符串连接性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16078177/

相关文章:

python - 在python中组合两个字符串

python - 将非零列名转换为 Python 中的行

python - 将 BytesIO 保存到 Django ImageField

python - scrapy 500个请求后添加延迟

r - 粘贴网格——expand.grid用于字符串连接

tsql - T-SQL : Best way to handle NULL values in string concatenation

c# - 在 C# 中优化循环字符串连接的性能

c++ - 这个boost c++正则表达式代码有什么问题?

python - 如何处理 tkinter 主循环中的错误?

python - 与 line.rfind 相关的语法错误