【问题标题】:String concatenation in PythonPython中的字符串连接
【发布时间】:2011-03-23 06:05:07
【问题描述】:

您能否描述两种字符串连接方式之间的区别:简单的__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 表单总是会变慢

标签: python compilation internals object-identity


【解决方案1】:

从技术上讲,使用% 是字符串格式化,而不是串联。他们是两个完全不同的世界。

如果您了解字符串实习,那么您应该知道绝对不能保证两个字符串会占用与另一个字符串相同的内存。在您的示例中,前三个所做的事实纯属巧合。

我不是 100% 确定字符串格式化是如何工作的,但我知道它在底层 C 中的实现方式与连接不同 - 我认为它的工作方式与 ''.join(sequence) 类似,这也更快比+ 更大的字符串 - 请参阅this post 了解更多信息。

*有点。

【讨论】:

  • 好吧,不是串联,而是用同样的方式,返回几乎一样的结果。
  • 基本上,是的。字符串连接应该只用于较小的字符串,并且只在少数情况下使用(大约 7 次连接后,使用''.join() 会快得多)
【解决方案2】:

这是一个小练习:

>>> 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:是的。与运行 .py 文件的方式没有太大区别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
  • 2010-09-27
  • 1970-01-01
  • 2016-03-14
  • 2013-03-20
相关资源
最近更新 更多