python如何处理列表的解包、重定义和引用?

fre*_*m35 5 python list destructuring

我是 python 新手,我试图了解它如何处理列表解包方面的副本与引用。我有一个简单的代码片段,正在寻找关于它为何如此运行的解释。

arr = [1, 2, 3, 4]
[one, two, three, four] = arr
print(id(arr[0]), arr[0])
print(id(one), one)
one = 5
print(id(one), one)
Run Code Online (Sandbox Code Playgroud)

输出是:

(16274840, 1)
(16274840, 1)
(16274744, 5)
Run Code Online (Sandbox Code Playgroud)

我不确定为什么one当我尝试修改其内容时突然移动到不同的内存位置。

我正在使用 python 版本 2.7.18。

这是我的第一篇文章,所以如果我不遵守准则,我提前道歉。如果我违反了这些规定,请告诉我。

感谢您的所有回复。他们帮助我简化了对这段代码的误解:

var = 1
print(id(var), var)
var = 5
print(id(var), var)
Run Code Online (Sandbox Code Playgroud)

带输出:

(38073752, 1)
(38073656, 5)
Run Code Online (Sandbox Code Playgroud)

询问列表并解压它们完全是令人困惑的。

这很好地解释了: http://web.stanford.edu/class/archive/cs/cs106a/cs106a.1212/handouts/mutation.html

Car*_*ate 6

/地址id与变量/名称没有关联;它与变量所引用的数据相关联。

在本例中,该1对象位于 address 16274840,并且该5对象位于 address 16274744one = 5导致one现在引用5位于 location 的对象16274744


只是用 C 语言重新表述一下,我认为你的问题本质上可以归结为“为什么以下内容不修改 的第一个元素arr?” (我忽略了拆包,因为它实际上与问题无关):

arr = [1, 2, 3, 4]
one = arr[0]
one = 5
Run Code Online (Sandbox Code Playgroud)

我将该代码近似为以下 C,它也不会修改arr

int internedFive = 5;

int arr[4] = {1, 2, 3, 4};

int* one = &arr[0];
one = &internedFive;

printf("%d", arr[0]);  // Prints 1
Run Code Online (Sandbox Code Playgroud)

one最初指向 的第一个元素arr,但被重新分配为指向5one指针的重新分配对和最初指向的数据位置没有影响arr[0]

  • 不存在“不可变对象范例”。这是一个“引用语义”范例(例如,与 Java 处理非原始类型的方式相同,以及 C# 通常处理“类”类型的方式)。这并不是说某些物体很特殊,因为没有办法改变它们;而是因为它们是特殊的。关键点是*改变对象与重新分配名称*根本不同。 (2认同)

Sha*_*ger 5

one不是一个对象。它是绑定到对象的名称。当您重新分配时one = 5,您将其从包含 value 的对象重新绑定1到包含 value 的另一个对象5,但唯一one存储的是更新的引用,而不是值本身。

需要明确的是,您不能“修改 ; 的内容” intints 是不可变的。如果您想要一个可以修改对象内容而不修改地址的示例,请考虑:

lst = [0]
print(id(lst), lst)
lst[0] = 1
print(id(lst), lst)
Run Code Online (Sandbox Code Playgroud)

其中叶子始终lst保持不变,只是改变了said 的内容 listlist