【问题标题】:Altering one python list in dictionary of lists alters all lists [duplicate]更改列表字典中的一个 python 列表会更改所有列表 [重复]
【发布时间】:2012-12-08 04:48:13
【问题描述】:

可能重复:
Two separate python lists acting as one

这段代码创建了一个列表字典,键在usens。列表全是0s

usens = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 110, 111, 112, 113, 114,
         115, 116, 117, 118, 119, 302, 303, 306, 307, 308, 370, 371, 500,
         501, 1000, 1010, 1020, 1100, 1200, 1201, 1202, 2000, 2001, 2002
         ]
empty = [[0]*length]*len(usens)
data = dict(zip(usens, empty))
pprint.pprint(data, indent=5)

data[0][0] += 1
pprint.pprint(data, indent=5)

第一个漂亮的打印返回预期的(去除模糊):

{0: [0, 0, 0, 0, 0],
 1: [0, 0, 0, 0, 0],
 2: [0, 0, 0, 0, 0],
 3: [0, 0, 0, 0, 0],
 4: [0, 0, 0, 0, 0],
 5: [0, 0, 0, 0, 0],
 .....
 2001: [0, 0, 0, 0, 0],
 2002: [0, 0, 0, 0, 0]}

然后我这样做:data[0][0] += 1,期望第一个列表(索引 0)以 1 开头,但没有其他要更改的内容。

但是,所有列表都已修改:

{0: [1, 0, 0, 0, 0],
 1: [1, 0, 0, 0, 0],
 2: [1, 0, 0, 0, 0],
 3: [1, 0, 0, 0, 0],
 4: [1, 0, 0, 0, 0],
 .....
 2001: [1, 0, 0, 0, 0],
 2002: [1, 0, 0, 0, 0]}

为什么,我怎样才能使它只修改一个列表?

【问题讨论】:

标签: python list dictionary


【解决方案1】:

empty = [[0]*length]*len(usens) 将创建同一列表的len(usens) 副本,这与具有相同内容的len(usens) 列表不同。

试试empty = [[0]*length for i in range(len(usens))]

【讨论】:

    【解决方案2】:

    使用* 创建副本;对于[0] 很好,因为它正在复制一个不可变的标量;但外部 * 创建相同列表的副本(即复制引用)。你可以使用类似的东西:

    empty = [0]*5
    data = {n:list(empty) for n in usens}
    

    (一个字典理解)来创建你的列表(如果使用 Python 2.7+)。使用list 进行复制。

    【讨论】:

    • 实际上,使用*不会创建副本。问题在于缺少副本。您对同一个列表有很多引用,而不是您认为得到的副本。
    • 取决于如何使用“复制”一词。它创建引用的副本;与值的副本没有不同的引用(就像copy.deepcopy 那样)。不过,如果他说“多次引用”可能会更清楚。
    猜你喜欢
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 2015-06-29
    相关资源
    最近更新 更多