我想在python中进行字符串赋值。但是,在python中,'str'对象不支持项目赋值。
如果我想做这项任务,s[head] = s[tail]
,我想出两个想法:
1.
s[:head]+s[tail]+s[(head+1):tail]+s[head]+s[(tail+1):]
2.
temp = list(s)
temp[head] = temp[tail]
s = ''.join(temp)
我的问题是这两者之间的时间复杂度是多少?当我尝试一些大型例子时,我发现第二个解决方案比第一个解决方案更快,但我不知道为什么。有人可以帮我解释一下吗?
答案 0 :(得分:1)
当您使用+
连接2个字符串时,必须分配一个新的字符串对象,并且必须将2个源字符串复制到它。
因此,在第一个选项中,您将通过切片创建5个新字符串,然后在连接操作期间创建另外4个字符串。这总共有9个字符串分配和复制操作,然后需要取消分配8个中间字符串。
在第二个选项中,您可以从字符串创建列表,修改其中一个列表项,然后加入结果列表。 str.join
方法比逐个连接更有效,因为它分两个阶段进行。在第一阶段,它扫描列表中的字符串以确定目标字符串所需的总长度,分配该字符串,然后在第二阶段再次扫描列表以复制字符串数据。 (FWIW,这使得将列表理解传递给.join
比传递等效的生成器表达式更有效,因为.join
必须将gen exp运行到列表中才能执行其2次扫描。 / p>
自Python 2.5(IIRC)以来,字符串连接已经过优化,以提高a = a + b
和a = b + a
连接的速度,但对于更一般的情况,并没有太多可以做的事情,并且即使是我刚刚提到的简单案例,当字符串长度大于1000左右时,它比使用.join
要慢得多。
但是,这些操作的确切速度取决于您使用的Python版本。当然,为了公平地比较+
与.join
,我们需要时间执行相同的操作,而算法不会。
正如Stefan在评论中指出的那样,对于你的算法.join
实际上可能会更慢,即使对于大字符串也是如此。底线是:在编码时要注意一般的Python习语,但一般规则不能替代测量。因此,对在软件+硬件上运行的典型数据进行操作的实际代码进行速度测试。在可行的情况下,使用最新版本的Python。 (OTOH,Python 2上的一些字符串操作实际上可以更快,因为它们使用ASCII / Latin1字节字符串而不是完整的Unicode字符串完成。)