使用列表理解在 Python 中设置唯一词典列表

Using list comprehension to setup a list of unique dictionaries in Python

我有以下字典

stocklist = {'a': 0, 'b': 0, 'c': 0}

我想设置一个 HEIGHT by WIDTH 的网格,其中网格中的每个单元格都有其自己独特的具有不同值的库存清单版本。这行得通吗?

stockmap = [[stocklist for w in range(WIDTH)] for h in range(HEIGHT)]

我还有其他宽度乘高度列表,其中每个单元格只包含一个值,它们工作正常。

但在此之前,我尝试使用 类 来解决我的问题,但这是一场噩梦,因为我的实例包含一个始终相同的列表。

我担心如果我开始编写上面的代码,我最终会遇到同样的问题。

在您的示例中,网格的每个 'cell' 都将指向同一个字典 - stocklist。所以如果你修改一个 'cell' 实际上所有的都会改变。

如果您需要在每个单元格中存储不同的字典,您应该创建库存清单的深层副本。

尝试:

import copy
stocklist = {'a': 0, 'b': 0, 'c': 0}
stockmap = [[copy.deepcopy(stocklist) for w in range(WIDTH)] for h in range(HEIGHT)]

在这个简单的例子中,您的 stocklist 不包含任何嵌套字典

`stockmap = [[dict(stocklist) for w in range(WIDTH)] for h in range(HEIGHT)]`

会起作用。但是请记住,如果您的 stocklist 类似于 {'a': 0, 'b': {'c': 0}},则内部嵌套字典 {'c': 0} 将不会被深度复制,每个 'cell' 将共享该字典。

正如我上面所建议的,您需要实例化一个新对象,例如使用 dict

stockmap = [[dict(stocklist) for w in range(WIDTH)] for h in range(HEIGHT)]

否则将使用完全相同的字典实例。

我们来看看:

以你为例

>>> HEIGHT = 3
>>> WIDTH = 3
>>> stocklist = {'a': 0, 'b': 0, 'c': 0}
>>> stockmap = [[stocklist for w in range(WIDTH)] for h in range(HEIGHT)]
>>> stockmap
[[{'a': 0, 'b': 0, 'c': 0}, {'a': 0, 'b': 0, 'c': 0}, {'a': 0, 'b': 0, 'c': 0}], [{'a': 0, 'b': 0, 'c': 0}, {'a': 0, 'b': 0, 'c': 0}, {'a': 0, 'b': 0, 'c': 0}], [{'a': 0, 'b': 0, 'c': 0}, {'a': 0, 'b': 0, 'c': 0}, {'a': 0, 'b': 0, 'c': 0}]]
>>> stocklist['a']=9
>>> stockmap
[[{'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}], [{'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}], [{'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}]]

你可以清楚地看到,修改原始字典中的一项会影响新创建的列表(网格)

而在做

>>> stockmap = [[dict(stocklist) for w in range(WIDTH)] for h in range(HEIGHT)]
>>> stockmap
[[{'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}], [{'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}], [{'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}]]
>>> stocklist['a']=5
>>> stockmap
[[{'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}], [{'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}], [{'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}, {'a': 9, 'b': 0, 'c': 0}]]

保持网格不变

注意:正如@damgad 正确指出的那样,dict 不适用于嵌套词典。在这种情况下,您需要使用 copy.deepcopy