Python中的字符串拼接

3
你能描述一下两种字符串拼接的不同方式吗:简单的__add__运算符和%s模式? 我对这个问题进行了一些调查,发现使用%s(不使用括号形式)会稍微快一些。
还有另一个问题出现了:为什么'hell%s' % 'o'的结果引用了另一个内存区域,而'hell%s' % ('o',)没有?
以下是一些代码示例:
l = ['hello', 'hell' + 'o', 'hell%s' % 'o', 'hell%s' % ('o',)]
print [id(s) for s in l]

结果:

[34375618400, 34375618400, 34375618400, 34375626256]

附言:我知道字符串内部化 :)


我认为你应该使用变量进行测试,我怀疑这些简单的用法可能会在编译阶段进行优化;我的猜测是,如果模式是一个变量字符串,那么“%s”形式总是比较慢的。 - UncleZeiv
2个回答

7

这是一个小练习:

>>> def f1():
    'hello'


>>> def f2():
    'hel' 'lo'


>>> def f3():
    'hel' + 'lo'


>>> def f4():
    'hel%s' % 'lo'


>>> def f5():
    'hel%s' % ('lo',)


>>> for f in (f1, f2, f3, f4, f5):
    print(f.__name__)
    dis.dis(f)


f1
  1           0 LOAD_CONST               1 (None) 
              3 RETURN_VALUE         
f2
  1           0 LOAD_CONST               1 (None) 
              3 RETURN_VALUE         
f3
  2           0 LOAD_CONST               3 ('hello') 
              3 POP_TOP              
              4 LOAD_CONST               0 (None) 
              7 RETURN_VALUE         
f4
  2           0 LOAD_CONST               3 ('hello') 
              3 POP_TOP              
              4 LOAD_CONST               0 (None) 
              7 RETURN_VALUE         
f5
  2           0 LOAD_CONST               1 ('hel%s') 
              3 LOAD_CONST               3 (('lo',)) 
              6 BINARY_MODULO        
              7 POP_TOP              
              8 LOAD_CONST               0 (None) 
             11 RETURN_VALUE         

正如您所看到的,所有简单的字符串拼接和格式化都是由编译器完成的。而最后一个函数需要更复杂的格式化,因此我猜测它实际上是被执行了。由于所有这些对象都是在编译时创建的,它们都具有相同的ID。


那么,如果我在Python控制台中输入代码,它会先编译,然后再解释吗? - Roman Bodnarchuk
@Roman:是的。与运行 .py 文件的方式没有太大区别。 - SilentGhost

1

使用%在技术上是字符串格式化,而不是连接。它们是两个完全*不同的世界。

如果你知道字符串拼接,那么你应该知道没有任何保证两个字符串将占用与另一个相同的内存。在你的例子中前三个字符串占用相同内存只是巧合。

我不确定字符串格式化是如何工作的,但我知道它在底层 C 中的实现方式不同于拼接 - 我认为它更像是''.join(sequence)这种方式,对于大字符串也比+更快 - 更多信息请参见this post

*有点。


好的,这不是连接,但用法相同并返回几乎相同的结果。 - Roman Bodnarchuk
基本上是的。字符串连接应该仅用于较小的字符串和少数情况(大约在7次连接后,使用''.join()速度更快) - Wayne Werner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接