追加将覆盖列表中的现有数据

Pra*_*pta 7 python python-2.7

我有一个python程序,应该将列表附加到全局变量,但是不附加它就是覆盖列表。这是我制作的演示函数,其工作原理相同:

var_gobal = []

def parse(list_parse,stack):
    for element in list_parse:
        stack.append(element["a"])
        print(stack)
        global var_gobal
        var_gobal.append(stack)

to_parse = [{"a":"abc","b":"bcd","c":"cde"},{"a":"def","b":"efg","c":"ghi"}]
parse(to_parse,[])
print (var_gobal)
Run Code Online (Sandbox Code Playgroud)

预期输出应为

[['abc'], ['abc', 'def']]
Run Code Online (Sandbox Code Playgroud)

但是我得到了

[['abc', 'def'], ['abc', 'def']]
Run Code Online (Sandbox Code Playgroud)

列表的第一个元素被覆盖。为什么会这样呢?

stu*_*ent 6

您可以使用切片stack = stack[:] + [element["a"]]代替append列表方法:

var_gobal = []

def parse(list_parse,stack):
    global var_gobal

    for element in list_parse:
        stack = stack[:] + [element["a"]]
        print(stack)
        var_gobal.append(stack)

to_parse = [{"a":"abc","b":"bcd","c":"cde"},{"a":"def","b":"efg","c":"ghi"}]
parse(to_parse,[])
print (var_gobal)
Run Code Online (Sandbox Code Playgroud)

输出:

['abc']
['abc', 'def']
[['abc'], ['abc', 'def']]
Run Code Online (Sandbox Code Playgroud)

或者,使用stack = stack + [element["a"]]也会产生相同的结果。

要查看差异,我们可以查看以下示例:

my_list = ['a', 'b']
tmp = []
global_var = [] 

for i in my_list:
    tmp.append(i)
    global_var.append(tmp)

global_var
Run Code Online (Sandbox Code Playgroud)

这输出global_var为[['a', 'b'], ['a', 'b']]。

虽然,在每次迭代中tmp附加到,但在每次附加时,所有引用(或所有指向)都会更改。相反,如果使用或 ,则首先使用所有元素创建新列表,因为使用了:global_varmy_listtmpslice+[:]

my_list = ['a', 'b']
tmp = []
global_var = [] 

for i in my_list:
    tmp = tmp[:] + [i]
    global_var.append(tmp)

global_var
Run Code Online (Sandbox Code Playgroud)

结果如下: [['a'], ['a', 'b']]

  • 这是有效的,但为什么 `stack.append()` 会导致问题? (2认同)
  • 与上面的情况类似,最初的 stack 附加了 `['abc']` 并附加到了 `global_var`。但是在下一次迭代中,相同的堆栈附加了 `def` 并变成了 `['abc', 'def']`。当我们追加这个更新的 `stack` 时,所有使用过的 `stack` 的位置现在都将具有相同的更新值(数组是通过引用传递的,这里的 stack 只是一个数组或列表),所以即使之前附加的 `stack` 也会发生变化. (2认同)

Pat*_*vic 5

您必须将堆栈复制到var_global而不是附加引用。

var_gobal.append(stack.copy())
Run Code Online (Sandbox Code Playgroud)