Python 中列表的内存地址如何工作?



简单代码

c=[1]
print (c is [1])
#return false while if c = 1 integer then it would be true

我检查了 id,然后结果

print(id([1]))
print(id([2]))
print(id([1,2,3]))
print(id(c))
#2523446278656 same id but diffrent from id(c)
#2523446278656 same id
#2523446278656 same id
#2523446278848

所有该死的列表值都具有相同的id??(现在我明白了每次调用打印函数时 id 都会重置)

当我只是添加一个简单的代码时

d=c[:]

除了 id(c) 之外的所有 id 神奇地改变,id(d) 也指向上面的 id([1])

print(id([1]))
print(id([2]))
print(id([1,2,3]))
print(id(c))
print(id(d))
#2523446278592 diffrent id than aboved
#2523446278592 diffrent id than aboved
#2523446278592 diffrent id than aboved
#2523446278848 the same id as id(c) aboved
#2523446278656 now id(d) is somehow the same with id[1],[1,2],[1,2,3] above
请注意,如果我只输入"c[:]">

而不是"d=c[:]",它们仍然是相同的 id。此外,我上面的整个代码都在同一个脚本上并执行一次。

编辑以获得请求权限:现在我明白了 Python 中有一个垃圾收集器,每次我将值分配给变量时,垃圾收集器都会来获取旧 id,然后下次我分配它将再次使用该 id

[1]并不总是存在于2523446278592(例如)内存一直被分配和重新分配。因此,对于print(id([1])),它将[1]分配给id,以便可以对其进行评估,存储等,但是在该行中使用后不再需要它,因此2523446278592处的空间现在再次可用,因此下一行print(id([2]))现在可以将[2]分配给id 2523446278592因为它是空的。但是,print(id(c))不使用2523446278592(尽管它可用),因为c已经存储在不同的位置(而是打印)。然后,由于d = c[:]创建了一个新列表(不是在id(c)),因此它可以使用由2523446278592表示的开放空间。

但也要注意这里的区别:

c = [1]
print(id([1]))
print(id([2]))
print(id([1,2,3]))
print(id(c))
d = c[:]
print(id(d))

这按照您所说打印,因为d需要下一个空闲 ID(打印后释放的 on)

而:

c = [1]
d = c[:]
print(id([1]))
print(id([2]))
print(id([1,2,3]))
print(id(c))
print(id(d))

这的工作方式不同,因为d是在打印之前分配的,因此打印行不能将d的 id 用于[1]等,因为它不是自由的,所以它是不同的。这种情况的输出是:

2346573042880
2346573042880
2346573042880
2346568705216
2346568705408 #d is different from the print lines

欢迎来到临时物品的世界!当你写c == [1]时,你会创建一个新的列表对象([1])并在其上设置一个引用(c)。对象的生存期将是其最后一个引用之一。

但是当你写id([1])时,你确实创建了一个新对象(因此是一个不同的id),但没有设置引用来保持它的活动状态,所以它立即被销毁,它的地址可用于下一个创建的对象......

顺便说一句,d = c,您可以在同一个对象上创建一个新引用,以便它们具有相同的 id。

最后但并非最不重要的一点是,解释器管理其内存和对象 ID 的方式仅取决于实现细节,您甚至不应该尝试猜测它......绝对不要依赖任何模式!

最新更新