【问题标题】:Difference between list increment shortcut (a+=[1]) and longer way (a=a+[1])列表增量快捷方式 (a+=[1]) 和更长的方式 (a=a+[1]) 之间的区别
【发布时间】:2020-05-22 13:50:12
【问题描述】:

我使用的是 Python 3.7.5 版

我发现我的代码中存在用于转换某些数据的错误,我已尽我所能创建该问题的最小工作示例。

首先,这是我期望的代码:

a = ['foo','bar']
b = ['spam','eggs']
c = {'glue':a, 'dill':b}

for i in range(23,25):
    c['dill'] = c['dill'] + [i]
print(b)
print(c)
# ['spam', 'eggs']
# {'glue': ['foo', 'bar'], 'dill': ['spam', 'eggs', 23, 24]}

for循环中的代码不会影响b的值。

但是当我切换到使用增量运算符时,情况就不再是这样了:

a = ['foo','bar']
b = ['spam','eggs']
c = {'glue':a, 'dill':b}

for i in range(23,25):
    c['dill'] += [i]
print(b)
print(c)
# ['spam', 'eggs', 23, 24]
# {'glue': ['foo', 'bar'], 'dill': ['spam', 'eggs', 23, 24]}

在使用 Python 时,我一直有这样的印象:

  1. a += 1a = a + 1 做了同样的事情
  2. 当一个变量基于另一个变量 (b=a) 定义时,对新变量 (b=f(b)) 的后续更改不会影响原始变量

上面的例子似乎违反了这两个假设。怎么回事?

【问题讨论】:

  • 这个答案stackoverflow.com/a/823878/7648578 似乎涵盖了它。 "+ 总是返回一个新分配的对象,但如果对象是可变的,+= 应该(但不必)就地修改对象(例如listdict,但int 和@987654335 @ 是不可变的)。”

标签: python python-3.x


【解决方案1】:

您的假设 1 和 2 对于数值类型(不可变类型,不确定 Python 中的正确术语)如数字或字符串是正确的,但不适用于列表。

这两个问题都与同一件事有关:Python 中的list(数组)变量是对可变对象的引用

a = [1, 2, 3] 创建一个列表。

b = a 表示b 现在是对与a 相同列表的引用。任何变异引用的数组的动作都会“影响两个变量”。

如果您为其中一个变量分配一个新列表,它们将不再引用内存中的同一个对象。

请参阅What does += mean in Python?(感谢 nocimambi 提供链接)以了解有关 += 如何变异同一数组的详细信息,而 + 确实创建了一个新数组

【讨论】:

  • 谢谢!我不知道 Python 中的 references。似乎对我的实际代码的一个简单修复是编写 b=a+[] 而不是 b=a 以便 b 不引用与 a 相同的对象。
  • @zandergordan 没错!
猜你喜欢
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
  • 1970-01-01
  • 2016-03-15
  • 2019-01-12
  • 1970-01-01
  • 2014-09-07
  • 2016-02-17
相关资源
最近更新 更多