在Python中追加与重新定义变量
首先,如果我的问题在其他地方得到了回答,请允许我先道歉。我回顾了Stack Overflow建议的几个问题,但没有一个包含我正在寻找的答案。我也更感兴趣的是为什么会发生这种情况,而不是为了避免这个问题而采取的任何变通办法。我试着回答我自己的问题,但我只能把问题简化成一个更简单的问题。无论如何,有人能帮我理解下面两组代码之间的差异吗?这样我就可以理解不同输出的原因了 版本1(在变量在Python中追加与重新定义变量,python,python-2.7,append,global-variables,Python,Python 2.7,Append,Global Variables,首先,如果我的问题在其他地方得到了回答,请允许我先道歉。我回顾了Stack Overflow建议的几个问题,但没有一个包含我正在寻找的答案。我也更感兴趣的是为什么会发生这种情况,而不是为了避免这个问题而采取的任何变通办法。我试着回答我自己的问题,但我只能把问题简化成一个更简单的问题。无论如何,有人能帮我理解下面两组代码之间的差异吗?这样我就可以理解不同输出的原因了 版本1(在变量dog上使用append): cat = [ ] dog = [ ] dog.append(1) print dog
dog
上使用append):
cat = [ ]
dog = [ ]
dog.append(1)
print dog # [1]
print cat # [ ]
cat.append(dog)
print dog # [1]
print cat # [ [1] ]
dog.append(1)
print dog # [1, 1]
print cat # [ [1, 1] ]
dog.append(1)
print dog # [1, 1, 1]
print cat # [ [1, 1, 1] ]
cat.append(dog)
print dog # [1, 1, 1]
print cat # [ [1, 1, 1], [1, 1, 1] ]
cat = [ ]
dog = [ ]
dog = [1]
print dog # [1]
print cat # [ ]
cat.append(dog)
print dog # [1]
print cat # [ [1] ]
dog = [1, 1]
print dog # [1, 1]
print cat # [ [1] ]
dog = [1, 1, 1]
print dog # [1, 1, 1]
print cat # [ [1] ]
cat.append(dog)
print dog # [1, 1, 1]
print cat # [ [1], [1, 1, 1] ]
第2版(将狗重新定义为不同的列表):
cat = [ ]
dog = [ ]
dog.append(1)
print dog # [1]
print cat # [ ]
cat.append(dog)
print dog # [1]
print cat # [ [1] ]
dog.append(1)
print dog # [1, 1]
print cat # [ [1, 1] ]
dog.append(1)
print dog # [1, 1, 1]
print cat # [ [1, 1, 1] ]
cat.append(dog)
print dog # [1, 1, 1]
print cat # [ [1, 1, 1], [1, 1, 1] ]
cat = [ ]
dog = [ ]
dog = [1]
print dog # [1]
print cat # [ ]
cat.append(dog)
print dog # [1]
print cat # [ [1] ]
dog = [1, 1]
print dog # [1, 1]
print cat # [ [1] ]
dog = [1, 1, 1]
print dog # [1, 1, 1]
print cat # [ [1] ]
cat.append(dog)
print dog # [1, 1, 1]
print cat # [ [1], [1, 1, 1] ]
我对Python中append方法的天真理解使我期望版本1具有与版本2相同的输出。我不明白为什么追加
dog
会以任何方式影响变量cat
,除非我通过追加或其他方式明确更改cat
。在python中,将“名称”视为对对象的引用是有帮助的。换言之:
cat = []
名称cat
是对列表实例的引用每个对象都可以有多个引用
cat = tiger = []
这里cat
和tiger
引用了相同的列表
cat = []
tiger = cat
同样,cat
和tiger
引用相同的列表
cat = []
tiger = cat
容器类型(例如列表
)可以包含对其他对象的多个引用
cat = []
dog = [cat]
在这种情况下,dog
中的第一个元素是与cat
引用的列表相同的引用。因此,如果我附加到由cat
引用的列表,则由dog
的第一个元素引用的列表也将看到更改(因为它们引用的是list
的相同实例)
当然,如何将引用放入容器并不重要:
cat = []
dog = []
dog.append(cat)
在python中,将“名称”视为对对象的引用是很有帮助的。换言之:
cat = []
名称cat
是对列表实例的引用每个对象都可以有多个引用
cat = tiger = []
这里cat
和tiger
引用了相同的列表
cat = []
tiger = cat
同样,cat
和tiger
引用相同的列表
cat = []
tiger = cat
容器类型(例如列表
)可以包含对其他对象的多个引用
cat = []
dog = [cat]
在这种情况下,dog
中的第一个元素是与cat
引用的列表相同的引用。因此,如果我附加到由cat
引用的列表,则由dog
的第一个元素引用的列表也将看到更改(因为它们引用的是list
的相同实例)
当然,如何将引用放入容器并不重要:
cat = []
dog = []
dog.append(cat)
将变量指定给列表时
dog = []
变量“dog”只存储对列表对象的引用,该对象存在于内存中的某个地方
如果重新分配变量“dog”
您已经创建了一个新的列表对象,并存储了对它的引用。如果没有对旧列表对象的引用,它将被垃圾收集(正确删除),因为它永远无法访问。但是,可以将对它的引用存储在另一个对象中
cat.append(dog) # Stores a reference to the old list
dog = [1,1] # Defined another new list
您不是通过名称“dog”将dog插入cat,而是通过引用内存中的列表对象。现在,旧的“dog”不会被垃圾收集,因为它被cat引用。现在,对dog引用的列表所做的更改不会影响“cat”,因为当您为列表分配变量时,这两个列表是不同的
dog = []
变量“dog”只存储对列表对象的引用,该对象存在于内存中的某个地方
如果重新分配变量“dog”
您已经创建了一个新的列表对象,并存储了对它的引用。如果没有对旧列表对象的引用,它将被垃圾收集(正确删除),因为它永远无法访问。但是,可以将对它的引用存储在另一个对象中
cat.append(dog) # Stores a reference to the old list
dog = [1,1] # Defined another new list
您不是通过名称“dog”将dog插入cat,而是通过引用内存中的列表对象。现在,旧的“dog”不会被垃圾收集,因为它被cat引用。现在,对dog引用的列表的更改不会影响“cat”,因为这两个列表是不同的在python中,所有内容都是一个对象,并将对象视为内存位置 追加时,修改的是存储在对象中的值,而不是内存位置 将列表狗作为元素附加到cat时,此元素也指向同一对象。换句话说,有两个元素访问相同的对象,一个是变量“dog”,另一个是“cat”中的元素。因此,您对对象所做的任何更改都可以在“dog”和“cat”中看到。这就是版本1中发生的情况 在版本2中,在第一次附加之后,您创建了一个新对象并将其分配给变量dog。现在变量“dog”和“cat”中的元素引用不同的对象 如果您不希望对“狗”所做的更改对“猫”可见,请使用
cat.append(dog[:])在python中,一切都是一个对象,并将对象视为内存位置 追加时,修改的是存储在对象中的值,而不是内存位置 将列表狗作为元素附加到cat时,此元素也指向同一对象。换句话说,有两个元素访问相同的对象,一个是变量“dog”,另一个是“cat”中的元素。因此,您对对象所做的任何更改都可以在“dog”和“cat”中看到。这就是版本1中发生的情况 在版本2中,在第一次附加之后,您创建了一个新对象并将其分配给变量dog。现在变量“dog”和“cat”中的元素引用不同的对象 如果您不希望对“狗”所做的更改对“猫”可见,请使用