5

我来自 c 背景,是 python 的初学者。我想知道在 python 的情况下字符串是如何实际存储在内存中的。

我做了类似的事情

s="foo"

id(s)=140542718184424

id(s[0])= 140542719027040
id(s[1])= 140542718832152
id(s[2])= 140542718832152

我不明白每个字符是如何存储在内存中的,为什么 s 的 id 不等于 s[0] 的 id(就像它曾经在 c 中一样)以及为什么 s1 和 s2 的 id 相同?

4

3 回答 3

4

Python没有字符。对字符串进行索引会创建一个新字符串,如果您不保留对它的引用,它(就像其他所有对象一样)会立即消失。因此id(),您的示例中的 s 不能相互比较,只要对象存在,对象的 id 才是唯一的。特别是,id(s[0]) != id(s)因为前者是一个新的(临时)对象,并且id(s[1]) == id(s[2])因为在计算第一个操作数之后,第一个临时字符串被销毁,而第二个临时字符串被分配给先前释放的内存。后者是一个实现细节和巧合,不能依赖。

由于小字符串(连同整数、一些元组等)被实习等实现细节,有关字符串内存的推理变得更加复杂,因此some_str is other_str对于来自不同来源的相同字符串(例如,从索引到具有不同索引的字符串)可能是正确的.

于 2013-10-07T11:54:00.210 回答
1

这篇文章很好地解释了字符串是如何存储的。简要地:

当处理空字符串或一个字符的 ASCII 字符串时,Python 使用字符串实习。实习字符串充当单例,也就是说,如果您有两个相同的字符串被实习,那么内存中只有一个副本。

Python 在内部不使用 UTF-8 来提供对子字符串的持续访问:

s = 'hello world'
s[0]
s[7] 

两者都不需要从初始字符(或更准确地说,长度为 1 的第一个子字符串)到该i-th位置扫描字符串。

这就是为什么 Python 使用 Unicode 字符串的三种内部表示,每个字符有 1、2 或 4 个字节(Latin-1、UCS-2、UCS-4 编码)并且不使用空间优化的 UTF- 8.

于 2021-02-15T22:37:58.057 回答
0

这取决于实现,但一些实现(不仅是 Python,其他语言也是)可能会保留一组中等大小的常量值,以供预期的频繁使用。在 Python 的情况下,这些值可能是True, None, 'o', 1,等值2。这样,当需要其中一个常见值时,创建它就没有开销——只需引用现有值即可。

于 2013-10-07T11:54:30.100 回答