微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如果列表的元素指向相同的内存地址,那么两个列表如何不指向同一个对象?

如何解决如果列表的元素指向相同的内存地址,那么两个列表如何不指向同一个对象?

我初始化两个列表如下:

>>> a = [1]
>>> b = [1]

然后我在两个列表的索引 0 处找到元素的内存位置:

>>> id(a[0])
93961440619840
>>> id(b[0])
93961440619840

两个元素的地址是一样的。但是当我试图找出两个列表是否都指向同一个对象时,我得到 'False'

>>> a is b
False

我的问题是,如果列表的元素指向同一个内存,为什么列表不指向同一个对象?

解决方法

我的问题是,如果列表的元素指向同一个内存,为什么列表不指向同一个对象?

因为列表是可变对象,所以每个列表文字必须创建一个全新的列表对象,独立于之前的每个对象^[0]。否则

>>> a = []
>>> b = []
>>> a.append(1)
>>> print(b)

会打印 [1] 而不是空列表,这会很疯狂。

id(a[0])id(b[0]) 尽管字面量不同,但仍然相同的原因是 Python 可以 预分配/实习经常使用的 不可变 对象到更低的内存消耗。

这是一个不能依赖的实现细节,因为它是特定实现的内部属性并且它可以随时更改。目前,CPython 将预分配 -5 到 256(包括在内)之间的所有整数,因此即使您通过独立文字或通过计算创建它们,它们也将始终是相同的对象。

[0] 从技术上讲,cpython(又是一个特定实现的内部细节)维护对象的freelists,所以当一个列表被“收集”时,它真的被存储起来,以便下次我们可以重用分配需要一个列表,而不必重新分配和设置一个全新的列表。这意味着连续(但不是同时)使用的不同列表可以具有相同的 id,即使在此期间有很多其他分配。

,

只有索引 0 处元素的内存位置相等,而不是整个列表的内存地址。

a[0] is b[0] # This returns True

整个列表的内存位置不同:您可以通过键入来测试

id(a)
id(b)

Python 这样做是为了减少内存使用

,

如果您选中 a[0] is b[0],那么它将是 True。由于 a[0]b[0] 的元素是相同的,这就是为什么这些 id 也相同的原因。结果是True

a = [1]
b = [1]
print(a[0] is b[0])
print(id(a[0]),id(a[0]))

# Output
# True
# 1793259440 1793259440

现在为什么 a is b 是 False?因为 a 和 b 是不同的列表并且具有不同的 id

print(a is b)
print(id(a),id(b))

# Output
# False
# 9997064 9997800
,

ab 是不同的对象,所以 id(a) 不等于 id(b)

但是a[0]常量 1,等于b[0],并且它们的地址相同,以节省内存。

帮助这有帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。