Python:复制变量或使其中两个指向同一个对象之间的区别

时间:2018-06-15 22:47:50

标签: python-3.x

我已经使用了很长时间的Python,但我不知道对象和内存是如何工作的。

直到几天前,我认为alpha = gamma创建了一个名为alpha的变量,并在其中保存了gamma的副本,而没有将变量相互链接。但是,我最近注意到这种情况不会发生。两个变量实际上都指向同一个对象。然而,当您更改其中一个数据时,变量会变得独立(取决于变量)。

还有许多其他情况,变量的行为与您的预期不同。这是我遇到的一个例子:

>>> grid1=[[0]*4]*4
>>> grid2=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
>>> grid1 == grid2
True
>>> grid1[2][3]+=1
>>> grid2[2][3]+=1
>>> grid1
[[0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 1]]
>>> grid2
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 0, 0]]

我试图找到有关=和其他命令如何处理变量并找到some threads的更多信息,但我有很多问题我的答案我还不知道:

  • 为什么上面显示的行为与列表有关?
  • 应该做些什么来避免它(让grid1表现得像grid2)?
  • 这与变量的可修改性有什么关系吗?变量可以修改的真正含义是什么?
  • 变量是同一个对象还是不同的?你怎么知道命令是否创建了一个单独的变量(x+=y vs x = x + yappend vs +)?
  • 在上面的示例中是否会返回== false is无效,这两个变量是在不同的步骤中创建的,并且是独立的,所以它们不会处于记忆中的同一个位置)因为在grid1中所有列表都在内存中的同一位置,而在grid2中它们是独立的?

我无法在任何地方找到这些问题的答案,是否有人可以简单回答问题或提供解释这些问题的参考?感谢。

1 个答案:

答案 0 :(得分:0)

  1. 为什么上面显示的行为与列表有关?

    因为列表和其他可变集合在将它们设置为变量时不会创建新对象。

  2. 应该做些什么来避免它(使grid1表现得像grid2)?

    grid1=[[[0] for _ in range(4)] for _ in range(4)]会让它按照您的意愿运作。这是因为它实际上每次创建一个新列表而不是重复它(如[[0]*4]*4那样)。

  3. 这是否与变量的可修改性有关?变量可以修改的真正含义是什么?

    字符串之类的集合是不可变的,因此当您执行a = "hi";b = a; b += "!"时,b将设置为复制a的新字符串,然后复制到复制b并添加"!"的新字符串。
    列表代替对同一对象进行操作,因此当您执行a = [];b = a;b.append(1)时,b设置为a,然后将1追加到b(在内存中引用a)。 />
  4. 变量是同一个对象还是不同的?你怎么知道命令是否创建了一个单独的变量(x + = y vs x = x + y,追加vs +)?

    它更多地取决于数据结构而不是运营商或方法 可变类型:list,set,dict。
    不可变类型:元组,冻结,字符串。

  5. 在上面的示例中是否有一个==会返回false(不会起作用,这两个变量是在不同的步骤中创建的,并且是独立的,所以它们不会在内存中的相同位置),因为在grid1所有列表都在内存中的同一位置,而在grid2中它们是独立的?

    ==评估值的相等性(即,如果它们包含相同的值),而is评估两者是否是同一个对象。 (尝试在两个相同的列表上测试==is。第一种情况a = [1]; b = [1]和第二种情况a = [1]; b = a