这里有一个例子:
l = [1, 5, 9, 3]
h = l
h[0], h[2] = h[2], h[0]
print(h) # [9, 5, 1, 3]
print(l) # [9, 5, 1, 3]
h = h*2
print(h) # [9, 5, 1, 3, 9, 5, 1, 3]
print(l) # [9, 5, 1, 3]
我的理解是,调用设置h = l
将简单地将h
指向l
指向的同一内存项。那么为什么在最后3行中,h
和l
不会给出相同的结果呢?
l = [1, 5, 9, 3]
h = l
h[0], h[2] = h[2], h[0]
print(h) # [9, 5, 1, 3]
print(l) # [9, 5, 1, 3]
print id(h), id(l)
h = h * 2
print id(h), id(l)
print(h) # [9, 5, 1, 3, 9, 5, 1, 3]
print(l) # [9, 5, 1, 3]
如您所见,由于行h = h * 2
,h的id已更改。
为什么会这样呢?当您使用*
运算符时,它会创建一个新列表(新的内存空间)。在您的情况下,这个新列表被分配给旧的h引用,这就是为什么您可以看到在h = h * 2
之后id不同的原因。
如果您想了解更多关于此主题的内容,请确保查看Data Model链接。
这个赋值操作确实使得h指向与l相同的项目。但是,它并没有永久地将两者连接起来。当你使用h = h * 2改变h时,你告诉Python在内存中的其他位置构建一个加倍版本,然后让h指向加倍版本。你没有给出任何更改l的指令;那仍然指向原始项目。
h = h * 2
将 h
赋值给一个新的列表对象。
你可能希望 原地修改 h
:
h *= 2
print(h) # [9, 5, 1, 3, 9, 5, 1, 3]
print(l) # [9, 5, 1, 3, 9, 5, 1, 3]
h += h * 2
也可以。 :) - l'L'lh += h
吗? - Moses Koledoye每当你给一个变量赋值时,它的身份(内存地址)通常会改变-唯一不改变的原因是你碰巧把它赋了它已经持有的值。所以,你的语句h = h * 2
使得h成为一个全新的对象-其值恰好基于先前h的值,但这实际上与它的身份无关。
虽然有些棘手,但当你对列表进行乘法运算时,实际上是创建了一个新的列表。
l = [1, 5, 9, 3]
h = l
现在,“l”和“h”引用的是同一内存中的列表。
h[0], h[2] = h[2], h[0]
print(h) # [9, 5, 1, 3]
print(l) # [9, 5, 1, 3]
h
中的值,因此在 l
中的值也发生了变化。当你将它们视为同一对象的不同名称时,这就有意义了。h = h * 2
print(h) # [9, 5, 1, 3, 9, 5, 1, 3]
print(l) # [9, 5, 1, 3]
h * 2
相乘时,你正在创建一个 新的列表,所以现在只有 l
是原始的列表对象。>>> l = [1, 5, 9, 3]
>>> h = l
>>> id(h) == id(l)
True
>>> id(h)
139753623282464
>>> h = h * 2
>>> id(h) == id(l)
False
>>> id(h)
139753624022264
h
的id
如何改变了?与其他列表操作(如append()
)不同,*
运算符会创建一个新列表,而不是更改当前列表。>>> h.append(1000)
>>> id(h)
139753623282464 # same as above!
import numpy as np
print np.may_share_memory(l,k)
用于确认变量l和k是否共享同一内存
对于任何想了解如何测试两个变量是否实际指向同一个内存地址的人,可以使用is
关键字。
对于Python列表,is
也适用。或者,对于列表,可以使用元素级别(深入)比较来执行操作,使用==
运算符。
下面是一个例子:
>>> j = [1, 2, 3, 456]
>>> i = j
>>> i == j # element-wise comparison
True
>>> j is i # both variables point to the same memory address
True
>>> i is j
True
>>> j = [1, 2, 3, 456]
>>> i = [1, 2, 3, 456]
>>> i == j # element-wise comparison
True
>>> i is j # do they point to the same memory address?
False
h
时,您会更改h
指向的内容。 - user2357112h = l
设置会将指针h
指向l
。但是,将h = h*2
设置会将指针h
指向其他位置。 - BrenBarn