gpt4 book ai didi

就地for循环中的Python字符串连接?

转载 作者:行者123 更新时间:2023-12-04 12:27:28 26 4
gpt4 key购买 nike

我知道 Python 字符串是不可变的,这意味着

letters = "world"
letters += "sth"
连接后会给我一个不同的字符串对象
begin: id(letters): 1828275686960
end: id(letters): 1828278265776
但是,当我运行 for 循环附加到字符串时,结果是字符串对象在 for 循环期间保持不变:
letters = "helloworld"
print("before for-loop:")
print(id(letters))
print("in for-loop")

for i in range(5):
letters += str(i)
print(id(letters))
输出:
before for-loop:
2101555236144
in for-loop
2101557044464
2101557044464
2101557044464
2101557044464
2101557044464
显然是 letter 的底层字符串对象指向在 for 循环期间没有改变,这与字符串应该是不可变的概念相矛盾。
这是 Python 在幕后执行的某种优化吗?

最佳答案

来自 documentation :

id(object)

Return the “identity” of an object. This is an integerwhich is guaranteed to be unique and constant for this object duringits lifetime. Two objects with non-overlapping lifetimes may have thesame id() value.

CPython implementation detail: This is the address of the object in memory.


方法 id()在这种情况下,存储的字符串的内存地址为 source code向我们展示:
static PyObject *
builtin_id(PyModuleDef *self, PyObject *v)
/*[clinic end generated code: output=0aa640785f697f65 input=5a534136419631f4]*/
{
PyObject *id = PyLong_FromVoidPtr(v);

if (id && PySys_Audit("builtins.id", "O", id) < 0) {
Py_DECREF(id);
return NULL;
}

return id;
}
发生的事情是两个对象的生命结束和开始确实重叠。
Python 保证字符串的不变性,只要它们还活着。
article @kris 建议显示:
import _ctypes

a = "abcd"
a += "e"

before_f_id = id(a)

a += "f"

print(a)
print( _ctypes.PyObj_FromPtr(before_f_id) ) # prints: "abcdef"
字符串 a结束是生命并且不保证可以恢复给定内存位置,实际上上面的例子表明它是 重复使用 对于新变量。
我们可以看看它是如何实现的 under the hoodunicode_concatenate查看最后几行代码的方法:
res = v;
PyUnicode_Append(&res, w);
return res;
哪里 vw是表达式中的那些: v += w方法 PyUnicode_Append实际上是试图为新对象重用相同的内存位置, in detailPyUnicode_Append :
PyUnicode_Append(PyObject **p_left, PyObject *right):

...

new_len = left_len + right_len;

if (unicode_modifiable(left)
...
{
/* append inplace */
if (unicode_resize(p_left, new_len) != 0)
goto error;

/* copy 'right' into the newly allocated area of 'left' */
_PyUnicode_FastCopyCharacters(*p_left, left_len, right, 0, right_len);
}

关于就地for循环中的Python字符串连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69556269/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com