相关疑难解决方法(0)

如果 Python 字符串是不可变的,为什么当我使用 += 附加到它时它会保持相同的 id?

Python 中的字符串是不可变的,这意味着值不能更改。但是,当附加到以下示例中的字符串时,由于 id 保持不变,因此原始字符串内存看起来已被修改:

>>> s = 'String'
>>> for i in range(5, 0, -1):
...     s += str(i)
...     print(f"{s:<11} stored at {id(s)}")
... 
String5     stored at 139841228476848
String54    stored at 139841228476848
String543   stored at 139841228476848
String5432  stored at 139841228476848
String54321 stored at 139841228476848
Run Code Online (Sandbox Code Playgroud)

相反,在以下示例中,id 发生变化:

>>> a = "hello"
>>> id(a)
139841228475760
>>> a = "b" + a[1:]
>>> print(a)
bello
>>> id(a)
139841228475312
Run Code Online (Sandbox Code Playgroud)

python string reference string-concatenation immutability

102
推荐指数
2
解决办法
6958
查看次数

为什么天真的字符串连接在一定长度之上变成二次方?

通过重复的字符串连接来构建字符串是一种反模式,但我仍然很好奇为什么它的性能在字符串长度超过大约10**6后从线性切换到二次方:

# this will take time linear in n with the optimization
# and quadratic time without the optimization
import time
start = time.perf_counter()
s = ''
for i in range(n):
    s += 'a'
total_time = time.perf_counter() - start
time_per_iteration = total_time / n
Run Code Online (Sandbox Code Playgroud)

例如,在我的机器上(Windows 10,python 3.6.1):

  • 因为10 ** 4 < n < 10 ** 6,time_per_iteration几乎完全恒定在170±10μs
  • 因为10 ** 6 < n,time_per_iteration几乎是完全线性的,达到520μs n == 10 ** 7.

线性增长time_per_iteration相当于二次增长total_time. …

python cpython python-internals

13
推荐指数
1
解决办法
1019
查看次数

+ 与 f-string 的字符串连接

假设我有两个变量:

>>> a = "hello"
>>> b = "world"
Run Code Online (Sandbox Code Playgroud)

我可以通过两种方式连接它们;使用+

>>> a = "hello"
>>> b = "world"
Run Code Online (Sandbox Code Playgroud)

或者使用 f 字符串:

>>> a + b
"helloworld"
Run Code Online (Sandbox Code Playgroud)

哪种方式更好或更好的做法?有人告诉我 f-string 在性能和健壮性方面是更好的做法,我想详细了解原因。

python string performance python-3.x f-string

8
推荐指数
3
解决办法
2953
查看次数