【问题标题】:Python String Concatenation in for loop long strings [duplicate]for循环长字符串中的Python字符串连接[重复]
【发布时间】:2017-01-30 00:47:10
【问题描述】:

我已经听说过你不应该在 for 循环中进行字符串连接,因为字符串是不可变的,因此它会将连接计算为新的字符串实例,然后重新分配标识符。因此,如果结果有 n 个字符,则时间复杂度将为 O(n^2)

不好: 运行时间为 O(n^2)。迭代“+”连接。

letters = ""
for c in document:
    if c.isalpha():
        letters += c

良好: 运行时间为 O(n)。迭代追加,带有最终的 "".join()

document = ""
temp = []
for c in document:
    if c.isalpha(): 
        temp.append(c)
letters = "".join(temp)

同时我也读到了

“Python 解释器的一些后期实现已经开发了一种优化,以允许此类代码在线性时间内完成,..”

所以第一个解决方案也应该没问题?这是最新的python版本中的优化吗?

【问题讨论】:

  • 大多数pythonistas会使用理解:letters = ''.join([c for c in document if c.isalpha()])
  • @StefanPochmann 对不起我的错,字母应该在循环之外。复制粘贴错误。更正了两个 sn-ps。
  • @user1767754 第一个在第一行仍然有语法错误。还有一个奇怪的评论。

标签: python string time-complexity string-concatenation


【解决方案1】:

首先,你应该为你编写最易读的代码;只有在运行时出现问题时,才应该考虑优化:

letters = "".join(c for c in document if c.isalpha())

对于当前的 CPython 实现,join 比 '+' 快。

>>> def test():
...   s = ""
...   for x in range(1000):
...     s += 'x'
... 
>>> timeit.timeit(test)
157.9563412159987
>>> def test():
...   s = []
...   for x in range(1000):
...     s.append('x')
...   s = ''.join(s)
... 
>>> timeit.timeit(test)
147.74276081599965

【讨论】:

  • list comp 比genex 好
  • 差不多。
  • 我的问题可能不清楚,但我想知道 python 是否针对 += 进行了优化。
  • 这取决于实现。
【解决方案2】:

关键是一些实现。不是全部。如果您想确保您的代码在所有 python 实现上快速运行,请使用str.join。根据文档的大小,不同的方法会更快。但是,"".join(...) 非常符合 Python 风格,人们会更快地理解您的意图。因此,除非您有 很多small 文档,否则请坚持使用 str.join

但是,要使 str.join+= 的速度提高 10 倍,请使用 str.translate。不过,此解决方案专门用于删除单个字符。

from string import digits
translation_table = str.maketrans("", "", digits) 
# first two args about translating characters, third is for removing characters
letters = document.translate(translation_table)

这个速度提高的原因是python需要为文档中的每个字符创建一个新的字符串。 str.translate 不需要这样做,因此速度更快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-16
    • 2017-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    相关资源
    最近更新 更多