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) 通过重复的字符串连接来构建字符串是一种反模式,但我仍然很好奇为什么它的性能在字符串长度超过大约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μs10 ** 6 < n,time_per_iteration几乎是完全线性的,达到520μs n == 10 ** 7.线性增长time_per_iteration相当于二次增长total_time. …
假设我有两个变量:
>>> 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 ×3
string ×2
cpython ×1
f-string ×1
immutability ×1
performance ×1
python-3.x ×1
reference ×1