Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python永久赋值变量_Python_List_Reference - Fatal编程技术网

Python永久赋值变量

Python永久赋值变量,python,list,reference,Python,List,Reference,我刚开始学习python,遇到了一些奇怪的事情 以下代码为变量测试指定x=1和y=2的坐标。test2变量为自己分配与test相同的值,然后将test2的[x]值更改为旧的[x]值减去1。这很好,但是,当最后一部分被执行时,它不仅从test2中的[x]值减去1,而且对test变量中的[x]值也是如此 test = [1,2]; test2 = test; test2[1] = test2[1] - 1; 我发现执行以下操作效果很好,但我仍然不明白为什么第一个方法会更改test值以及test2值

我刚开始学习python,遇到了一些奇怪的事情

以下代码为变量测试指定x=1和y=2的坐标。test2变量为自己分配与test相同的值,然后将test2的[x]值更改为旧的[x]值减去1。这很好,但是,当最后一部分被执行时,它不仅从test2中的[x]值减去1,而且对test变量中的[x]值也是如此

test = [1,2];
test2 = test;
test2[1] = test2[1] - 1;
我发现执行以下操作效果很好,但我仍然不明白为什么第一个方法会更改test值以及test2值

test = [1,2];
test2 = test;
test2 = [test2[0] -1 ,test2[1]];
有人能解释一下为什么会这样吗

多谢各位
这是因为当您执行
test2=test
时,您没有复制列表的内容,而是简单地将
test2
的引用分配给原始列表。因此,对
test2
的任何更改也将影响
test

正确的方法是使用“复制”模块(或
copy()
,如果可以轻松复制的话)

import copy
test2 = copy.deepcopy(test) # deep copy

test2 = copy.copy(test)) # shallow copy

test2 = test[:] # shallow copy using slices

有关更深入的说明以及复制列表的其他方法,请参阅。

[1,2]
是一个数组,当您将其分配给
test
时,您会将一个引用分配给该数组进行测试。因此,当您执行
test2=test
时,您会将引用分配给另一个变量。对任何变量进行更改,数组都会更改

您的第二个示例是有效的,因为您创建了一个新的数组。您也可以这样做:

test = [1,2]
test2 = [test[0]-1, test[1]]

Python不执行赋值

它没有名称绑定

这是一个不同之处,它被解释得精彩而详细

在您的第一个示例中: 第一行将名称“test”绑定到由“[1,2]”表达式创建的列表对象。 第二行将名称“test2”绑定到绑定到“test”的同一个对象。 第三行修改绑定到“test2”的对象,该对象与绑定到“test”的对象相同

在第二个示例中: 第一行将名称“test”绑定到由“[1,2]”表达式创建的列表对象。 第二行将名称“test2”绑定到绑定到“test”的同一个对象。 第三行将名称“test2”绑定到由表达式“[test2[0]-1,test2]”创建的新对象

如果您确实希望两个具有相同值的独立列表绑定到不同的变量,则需要:

>>> test = [1, 2]
>>> test2 = list(test)
>>> test2[0] = 3
>>> print(test)
[1, 2]
>>> print(test2)
[3, 2]
请注意,这是一个浅拷贝列表,因此如果在该列表中找到相同的对象,那么在
test2
中更改元素的对象状态当然会影响
test

p、 在Python中,就像在Java中一样,赋值本身从不进行复制——rahter,赋值将另一个引用添加到与
=
右侧相同的对象(参数传递的方式相同).奇怪的是,你从来没有听说过这个概念,当时Python非常流行,Java甚至更流行(许多其他语言的工作方式也很相似,可能更复杂或更独特)

在Python中,根据您的具体用途,有几种方法——标准库的
copy
模块是一种流行的方法(函数
copy
,表示“浅层”拷贝,以及
deepcopy
——当然,对于“深度”拷贝,也就是说,不仅是容器,而且每个包含的项目都会递归地进行深度拷贝)


然而,通常情况下,你想要的是“一个新列表”——不管原始序列是列表、副本还是其他可编辑的东西,你可能不在乎:你想要一个新的
列表
实例,其项目与“其他东西”的项目相同。表达这一点的最佳方式是使用
列表(somethingelse)
--调用
列表
类型,该类型始终生成列表的新实例,并将您想要在新列表中显示其项的iterable作为参数。类似地,
dict(somemapping)
生成新的
dict
,以及
set(someiterable)
创建一个新的集合——调用一个类型来创建该类型的新实例是一个非常通用和有用的概念!

嗨,艾琳,谢谢你的回答。这是我第一次在任何语言中看到这一点。有没有办法只复制内容而不以任何方式链接它们?谢谢TheLorax@The_Lorax事实上,许多语言都表现为就是这样。最明显的一个总是使用副本的是PHP。对于这种示例,test2=test[:]就足够了。但是对于列表中的列表或其他讨厌的结构,deepcopy是最好的选择。这个
test2[1]=test2[1]-1;
与您的描述不匹配。
test2[1]
是数组的y值;x值应该是
test2[0]
。专业提示:在Python中,分号是不必要的,通常省略它们。:)但是:
a=5
b=a
a=6
断言(b==6)
-断言失败?这不是一个参考;对我来说似乎是一个副本?再次,这是由于名称绑定而不是赋值语义。当你说“b=a”时,你将名字“b”绑定到绑定到“a”的对象上,即5。然后,当您说“a=6”时,您正在(重新)将名称“a”绑定到对象“6”,但名称“b”仍然绑定到“5”。赋值是名称绑定的一种形式(其他名称绑定语句包括
def
class
import
表单
with
除了
with
with
as
子句,…)。重新绑定一个barename(即,绑定一个以前绑定到其他名称的barename)不会影响该名称以前绑定到的任何对象(也不会影响什么是或不绑定到其他名称)。