python是如何存储字符串的,以便“is”操作符可以处理文本的?

2024-04-20 03:06:56 发布

您现在位置:Python中文网/ 问答频道 /正文

在python中

>>> a = 5
>>> a is 5
True

但是

>>> a = 500
>>> a is 500
False

这是因为它将低整数存储为单个地址。但一旦数字开始变得复杂,每个int都会得到自己唯一的地址空间。这对我来说很有意义。你知道吗

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.

那么,为什么这不适用于字符串呢?字符串不是和大整数一样复杂吗?你知道吗

>>> a = '1234567'
>>> a is '1234567'
True

python如何有效地为所有字符串使用相同的地址?它不能像对数字那样保留一个包含所有可能字符串的数组。你知道吗


Tags: the字符串youanfalsetrueis地址
2条回答

它不存储所有可能字符串的数组,而是有一个哈希表,它指向当前声明的所有字符串的内存地址,由字符串的哈希索引。你知道吗

例如

当您说a = 'foo'时,它首先对字符串foo进行哈希运算,并检查哈希表中是否已经存在条目。如果是,那么变量a现在引用该地址。你知道吗

如果在表中找不到条目,python将分配内存来存储字符串,对foo进行哈希运算,并在表中添加一个带有分配内存地址的条目。你知道吗

请参见:

  1. How is the 'is' keyword implemented in Python?
  2. https://en.wikipedia.org/wiki/String_interning

这是一种叫做“实习”的优化技术。CPython识别equal values of string constants,不为新实例分配额外的内存,只是指向同一个实例(实习生),给出相同的id()。你知道吗

我们可以反复确认只有常量是这样处理的(可以识别像b这样的简单操作):

# Two string constants
a = "aaaa"
b = "aa" + "aa"

# Prevent interpreter from figuring out string constant
c = "aaa"
c += "a"

print id(a)         # 4509752320
print id(b)         # 4509752320
print id(c)         # 4509752176 !!

但是,您可以使用^{}手动强制将字符串映射到已存在的字符串:

c = intern(c)

print id(a)         # 4509752320
print id(b)         # 4509752320
print id(c)         # 4509752320 !!

其他口译员可能会有所不同。由于字符串是不可变的,因此更改其中一个字符串不会更改另一个字符串。你知道吗

相关问题 更多 >