Python名称/绑定-为什么不';t所有长度相同的列表;同一份名单;?
我知道Python中有大量关于指针和引用(或者更确切地说:名称和绑定!)的资源,但我很难理解最后一点: 我得到,如果Python名称/绑定-为什么不';t所有长度相同的列表;同一份名单;?,python,pointers,Python,Pointers,我知道Python中有大量关于指针和引用(或者更确切地说:名称和绑定!)的资源,但我很难理解最后一点: 我得到,如果a=1和b=1,它们都“绑定”到相同的精确1,并且将具有相同的id()(因此,我认为是内存地址)。如果你设置: a = [1, 2, 4] b = a b[0] = 45 # a is now [45, 2, 4] 因为a和b绑定到同一个列表(对象),一个列表中的更改会导致另一个列表的更改。类似地,a[0]和b[0]是同一个对象。该列表包含具有不同ID的其他对象-aka list
a=1
和b=1
,它们都“绑定”到相同的精确1,并且将具有相同的id()
(因此,我认为是内存地址)。如果你设置:
a = [1, 2, 4]
b = a
b[0] = 45
# a is now [45, 2, 4]
因为a
和b
绑定到同一个列表(对象),一个列表中的更改会导致另一个列表的更改。类似地,a[0]
和b[0]
是同一个对象。该列表包含具有不同ID的其他对象-aka list identity不绑定到其内容
好的。到现在为止,一直都还不错。我可以接受,有一些“未出生”的列表和数字在等待初始化(尽管只有一次!),Python会在我们需要它们时为它们分配一个内存空间。那么,如果我这样做了,为什么:
d = [1, 2]
e = [145, 7]
# id(d) and id(e) are not the same?!
Python中不应该只有一个2元素列表吗?这对我来说是一致的(然后只有一个1,一个2,一个145…等等)
任何解释都将不胜感激——其中包括将其与指针联系起来的解释(因为我对在内存管理级别做出的决策也有些困惑,但我认为这是Python的执行模型所关心的,而不是我!)您被CPython中针对
int
s的优化(即int缓存)所误导。见著名问题。这是记录在案的:
当前实现为所有对象保留一个整数对象数组
介于-5和256之间的整数,当您在该范围内创建整数时
实际上,只需返回对现有对象的引用
在几乎所有其他实例中,使用文字创建新对象。实际上,使用int
s超出该范围,您将看到正常行为:
>>> a = 100000
>>> b = 100000
>>> id(a)
4322630608
>>> id(b)
4322630640
>>> c = a
>>> id(a) == id(b)
False
>>> id(a) == id(c)
True
我几乎每天都要重复这一点,但Python中的赋值从不复制。您被CPython中针对
int
s的优化误导了,即int缓存。见著名问题。这是记录在案的:
当前实现为所有对象保留一个整数对象数组
介于-5和256之间的整数,当您在该范围内创建整数时
实际上,只需返回对现有对象的引用
在几乎所有其他实例中,使用文字创建新对象。实际上,使用int
s超出该范围,您将看到正常行为:
>>> a = 100000
>>> b = 100000
>>> id(a)
4322630608
>>> id(b)
4322630640
>>> c = a
>>> id(a) == id(b)
False
>>> id(a) == id(c)
True
我几乎每天都要重复这一点,但Python中的作业从来不会复制。
=
是一项作业
[1,2,3]
和10
是对象
如果编写10
或[1、2、3]
python将创建一个对象。如果不使用分配,垃圾收集器将删除它。但如果您这样做,python会将指向新创建对象的指针分配给给定的名称/变量,即:
a = [1, 2]
b = a
接下来,当您将一个变量分配给另一个变量时,python将从第一个变量复制一个指针,即:
a = [1, 2]
b = a
b
现在包含指向与a
相同对象的指针。但任何新创建的对象,即使内容相同,都是不同的对象。因此:
id(a) != id([1, 2])
现在,根据实现情况(因此它可以随时更改,您不应该依赖于它),可能会有一个提高速度效率的“快捷方式”,并且默认情况下可能会创建表示一些公共值的对象。这就是为什么在一些实现上
id(1)==id(1)
,但是什么让人困惑id(5555)!=id(5555)
=
是一个赋值
[1,2,3]
和10
是对象
如果编写10
或[1、2、3]
python将创建一个对象。如果不使用分配,垃圾收集器将删除它。但如果您这样做,python会将指向新创建对象的指针分配给给定的名称/变量,即:
a = [1, 2]
b = a
接下来,当您将一个变量分配给另一个变量时,python将从第一个变量复制一个指针,即:
a = [1, 2]
b = a
b
现在包含指向与a
相同对象的指针。但任何新创建的对象,即使内容相同,都是不同的对象。因此:
id(a) != id([1, 2])
现在,根据实现情况(因此它可以随时更改,您不应该依赖于它),可能会有一个提高速度效率的“快捷方式”,并且默认情况下可能会创建表示一些公共值的对象。这就是为什么在一些实现上
id(1)==id(1)
,但是什么让人困惑id(5555)!=id(5555)
Euhh…因为它们包含不同的元素?假设它们是同一个对象,您会为d[0]
返回什么1
或145
?似乎是一个奇怪的问题,有点像:为什么应该存在多个两个孩子的家庭?嗯……因为它们包含不同的元素?假设它们是同一个对象,您会为d[0]
返回什么1
或145
?似乎是个奇怪的问题,有点像:为什么应该有更多的两个孩子的家庭存在?但是如果我读对了这个问题,OP不是问int
s,而是问列表,这使得这个问题更奇怪。太神奇了-谢谢你了。我自己永远也找不到那个问题。我努力点头表示“这是合理的,这是有道理的,每件事只有一件!”谢天谢地,Python实际上并不是这样works@WillemVanOnsem是的,但是他的直觉被一个奇怪的关于文字的一般规则的例外所影响。@HFBrowning请阅读:并确保你理解它。谢谢链接@juanpa.arrivillaga,我会的。这个模型与R(所有东西都是复制的)完全不同