循环更新列表中的项目

时间:2013-05-07 20:59:12

标签: python list while-loop

我有这样的功能:

def main2():
    props = []
    prop_list = []
    i=0
    while (i < 10):
        new_prop = {
            'i': 1
        }
        props.append(new_prop)
        prop_list.append({'i': 1, 'props': props,})
        if i == 0:
            print prop_list
        i += 1
    print prop_list[0]

输出:

[{'i': 1, 'props': [{'i': 1}]}]
{'i': 1, 'props': [{'i': 1}, {'i': 1}, {'i': 1}, {'i': 1}, {'i': 1}, {'i': 1}, {'i': 1}, {'i': 1}, {'i': 1}, {'i': 1}]}

为什么最终打印与第一次打印不一样?当我追加新元素时,列表中先前添加的元素似乎正在更新。

2 个答案:

答案 0 :(得分:2)

有了这一行,

prop_list.append({'i': 1, 'props': props,})

dict包含props列表对象。这个列表在循环的后续迭代中发生变异:

props.append(new_prop)

prop_list[0]打印的最终值反映了这一变化。


这是孤立的同样的事情:

In [23]: x = []

In [24]: y = {'foo': x}

In [25]: y
Out[25]: {'foo': []}

In [26]: z = {'baz': x}

In [27]: x.append('bar')    # x is mutated

In [28]: y                 
Out[28]: {'foo': ['bar']}   # both y and z are affected

In [29]: z
Out[29]: {'baz': ['bar']}

如果您不希望发生这种情况,请复制一份清单。要制作props的浅表副本,请使用props[:]

prop_list.append({'i': 1, 'props': props[:]})

请注意,浅层副本props[:]新列表,其中包含与props完全相同的项目。这意味着如果props包含一个可变项,例如列表,那么改变该列表会影响props及其浅层副本。

props(递归)制作所有项目的副本,请使用

import copy
prop_list.append({'i': 1, 'props': copy.deepcopy(props)})

答案 1 :(得分:1)

在第

prop_list.append({'i': 1, 'props': props,})

props始终引用同一个对象,在顶部初始化

props = []

并附加到while循环的每次迭代中。