您看到的时差来自创建要传递给join 的列表。虽然您可以通过使用元组来获得小幅加速,但当只有几个短字符串时,它仍然比仅与 + 连接要慢。
如果你有一个可迭代的字符串开始,而不是一个以字符串作为属性的对象,那将是不同的。然后你可以直接在可迭代对象上调用join,而不需要为每个调用构建一个新的。
这是我对timeit 模块所做的一些测试:
import timeit
short_strings = ["foo", "bar", "baz"]
long_strings = [s*1000 for s in short_strings]
def concat(a, b, c):
return a + b + c
def concat_from_list(lst):
return lst[0] + lst[1] + lst[2]
def join(a, b, c):
return "".join([a, b, c])
def join_tuple(a, b, c):
return "".join((a, b, c))
def join_from_list(lst):
return "".join(lst)
def test():
print("Short strings")
print("{:20}{}".format("concat:",
timeit.timeit(lambda: concat(*short_strings))))
print("{:20}{}".format("concat_from_list:",
timeit.timeit(lambda: concat_from_list(short_strings))))
print("{:20}{}".format("join:",
timeit.timeit(lambda: join(*short_strings))))
print("{:20}{}".format("join_tuple:",
timeit.timeit(lambda: join_tuple(*short_strings))))
print("{:20}{}\n".format("join_from_list:",
timeit.timeit(lambda: join_from_list(short_strings))))
print("Long Strings")
print("{:20}{}".format("concat:",
timeit.timeit(lambda: concat(*long_strings))))
print("{:20}{}".format("concat_from_list:",
timeit.timeit(lambda: concat_from_list(long_strings))))
print("{:20}{}".format("join:",
timeit.timeit(lambda: join(*long_strings))))
print("{:20}{}".format("join_tuple:",
timeit.timeit(lambda: join_tuple(*long_strings))))
print("{:20}{}".format("join_from_list:",
timeit.timeit(lambda: join_from_list(long_strings))))
输出:
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
>>> test()
Short strings
concat: 0.5453461176251436
concat_from_list: 0.5185697357936024
join: 0.7099379456477868
join_tuple: 0.5900842397209949
join_from_list: 0.4177281794285359
Long Strings
concat: 2.002303591571888
concat_from_list: 1.8898819841869416
join: 1.5672863477837913
join_tuple: 1.4343144915087596
join_from_list: 1.231374639083505
因此,从现有列表加入总是最快的。如果单个项目很短,则与 + 连接会更快,但对于长字符串,它总是最慢。我怀疑concat 和concat_from_list 之间显示的差异来自于测试代码中函数调用中列表的解包。