当我们应用恒等运算符时,为什么两个具有完全相同数据的列表在 Python 中显示不同的内存地址?

问题描述

我有两个列表。

list1=["divyansh","jain","python"]
list2=["divyansh","python"]

两个列表具有完全相同的数据。

但是当我们应用 is 身份运算符时,它给我们错误,而且内存地址也不同。

我知道在python中一切都是对象。 如果我声明另一个具有相同数据值的变量,则这两个变量都指向同一个对象。 那么为什么这在列表数据类型的情况下不起作用。

我知道 python 在运行时为 int 范围内的 boolean 值分配认对象,范围为 0 到 255,string 值和空 list2

list1 最初创建时使用完全相同的值,为什么 x=300 y=300 print("Memory Address of variable x is : ",id(x)) print("Memory Address of variable y is : ",id(y)) print(x is y) print(x is not y) list1=["divyansh","python"] print("Memory Address of variable list1 is : ",id(list1)) print("Memory Address of variable list2 is : ",id(list2)) print(list1 is list2) print(list1 is not list2) Output : Memory Address of variable x is : 140185049313168 Memory Address of variable y is : 140185049313168 True False Memory Address of variable list1 is : 140185048064584 Memory Address of variable list2 is : 140185048053000 False True 指向某个不同的内存地址?

代码

tuple1=("divyansh","python")
tuple2=("divyansh","python")
print("Memory Address of variable tuple1 is : ",id(tuple1))
print("Memory Address of variable tuple2 is : ",id(tuple2))
print(tuple1 is tuple2)
print(tuple1 is not tuple2)

bytes1=[1,2,3]
bytes2=[1,3]
b1=bytes(bytes1)
b2=bytes(bytes2)
print(type(b1),type(b2))
print(id(b1))
print(id(b2))
print(bytes1 is bytes2)

a=10.5
b=10.5
print(type(a),type(b))
print(id(a))
print(id(b))
print(a is b)

c1=10+20j
c2=10+20j
print(type(c1),type(c2))
print(id(c1))
print(id(c2))
print(c1 is c2)

s1="Dj"
s2="Dj"
print(type(s1),type(s2))
print(id(s1))
print(id(s2))
print(s1 is s2)


f1=frozenset({"Dj"})
f2=frozenset({"Dj"})
print(type(f1),type(f2))
print(id(f1))
print(id(f2))
print(f1 is f2)

r1=range(10)
r2=range(10)
print(type(r1),type(r2))
print(id(r1))
print(id(r2))
print(r1 is r2)

Memory Address of variable tuple1 is : 140088826761792
Memory Address of variable tuple2 is : 140088826762008
False
True
<class 'bytes'> <class 'bytes'>
140088827913280
140088827388192
False
<class 'float'> <class 'float'>
140088827982304
140088827982304
True
<class 'complex'> <class 'complex'>
140088827402864
140088827402896
False
<class 'str'> <class 'str'>
140088826759184
140088826759184
True
<class 'frozenset'> <class 'frozenset'>
140088827366088
140088827365640
False
<class 'range'> <class 'range'>
140088846540448
140088827189840
False

创建对象比搜索它并为其分配相同的内存地址更耗时且成本更高。我知道对于可变对象这是不可能的,将来如果我们更改 list2,list1 数据将受到影响,因此它创建了 diff 对象。但是对于像 int、float、str 这样的基本不可变数据类型,它分配相同的内存,但对于字节、元组、frozenset、complex、range 等不可变数据类型,尽管它具有相同的数据值,但它不会分配相同的内存。>

其他数据类型示例:

pip install python-docx

解决方法

在对象编程的标准情况下:当您创建一个新对象时,语言/计算机将为它保留一个新的内存空间和地址。

在 Python 中,当您创建列表/容器等可变对象时,每个对象都有自己的内存地址。因此,您可以使用它们并修改其中一个,而无需修改第二个。这是必要的,如果地址相同,它将是一个相同的对象,具有两个名称/指针。

这对于处理 list1 和 list2 的变化而不修改另一个是必要的。因为列表是可变对象。

要检查内容身份,您必须检查列表中的每个项目。在 Python 中,'==' 运算符可用于与数字、列表、元组等内容进行比较。

它与 Python 中的不可变对象数字不同。由于它们是不可变的并且永远不会改变,Python 通过在重用相同的数字时指向相同的内存地址来优化它。 (是一种单例模式)

之所以做出这种优化选择,是因为每次创建一个新的数字对象都会消耗大量时间和内存。而且内存分配/释放的数量也会太多。