【问题标题】:Why does this python code give [3,3]? [duplicate]为什么这个python代码给出[3,3]? [复制]
【发布时间】:2017-03-13 12:23:06
【问题描述】:

考虑一下这段代码?

b = [[5], [3]]
a = b[1]
b[-1] += b.pop()
print(a)

这给出了[3,3]

您似乎无法通过将b[-1] += b.pop() 扩展为b[-1] = b[-1] + b.pop() 来解释它。

为什么会得到这个输出?

【问题讨论】:

标签: python list


【解决方案1】:

因为如果您使用b[-1]对第二个列表的引用只会被提取一次,接下来操作+= 完成,最后将其存储回列表中。所以b[-1] += b.pop()基本上相当于:

tmp = b[-1]  # tmp = [3]
tmp += b.pop() # tmp = [3,3], b = [[5]]
b[-1] = tmp # tmp = [3,3], b = [[3,3]]

(当然有tmp,上面的片段是在解释器级别完成的)

现在tmpb 中第二个列表的引用(所以tmp is a)。所以这意味着你用b.pop() 扩展inplace ab.pop()[3]。所以你要做的是用tmp 扩展tmp(当时是[3])。所以tmp(因此a变成[3,3])。所以b 现在是[[3,3]]

请注意,lists 的 x += y 不等同于 x = x+y。事实上,如果你写这样的代码:

>>> a = [1]
>>> b = a
>>> b = b + [2]
>>> print(a,b)
[1] [1, 2]

这将不会更新a(因为它没有完成就地)。而对于:

>>> a = [1]
>>> b = a
>>> b += [2]
>>> print(a,b)
[1, 2] [1, 2]

将导致ab 都是[1,2]。当然,通常+= 应该表现得像添加,但是添加是在 inplace 完成的,这会产生一些效果。

【讨论】:

    【解决方案2】:

    在打印 a 之前尝试打印 b[-1]。 b[-1] 指的是 b 中的最后一个元素,您正在向其中添加另一个元素。似乎发生这种情况是因为当您执行 a = b[1] 时,必须通过引用分配它,因为当 b[1](在这种情况下与 b[-1] 相同)更新时,a 也会更新。

    【讨论】:

      【解决方案3】:

      首先列表 b 中只有 2 个元素。

      b = [[5], [3]]
      a = b[1]
      
      print b[1] 
      # gives [3]
      print b[-1] 
      # also gives [3] because here -1 refers to the last element and there are 
      # only two elements.
      
      b[-1] += b.pop()
      # here you are appending 3 to [3] of b
      
      print b[-1] 
      print a
      # that is why when you print a it gives [3,3] as the b[1] value was 
      # appended to a in the second step itself and you are just printing here.
      

      希望你明白我想说的话..

      【讨论】:

        猜你喜欢
        • 2023-03-11
        • 2013-11-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-05
        • 2015-09-24
        • 1970-01-01
        相关资源
        最近更新 更多