【问题标题】:Using list comprehension to setup a list of unique dictionaries in Python使用列表推导在 Python 中设置唯一字典列表
【发布时间】:2015-11-06 12:41:12
【问题描述】:

我有以下字典

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

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

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

我还有其他按高度排列的宽度列表,其中每个单元格仅包含一个值,并且它们工作正常。

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

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

【问题讨论】:

  • 使用stockmap = [[dict(stocklist) for w in range(WIDTH)] for h in range(HEIGHT)]
  • 使用stocklist = {a: 0, b: 0, c: 0} 我得到一个错误。我正在使用 2.7 "TypeError: 'DataFrame' objects are mutable, thus they cannot be hashed"
  • @PierreLafortune 我已经编辑了原始代码,其中字典键缺少单括号:)
  • 对我上面的问题的跟进;然后访问列表的特定网格 deep.copy 的正确语法是什么?比如下面我要加一个

标签: python dictionary list-comprehension nested-lists


【解决方案1】:

在您的示例中,网格的每个“单元格”都将指向同一个字典 - stocklist。因此,如果您修改一个“单元格”,实际上所有单元格都会发生变化。

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

尝试:

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} 不会被深度复制,并且每个“单元格”都会共享该字典。

【讨论】:

    【解决方案2】:

    正如我上面建议的,您需要实例化一个新对象,例如使用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

    【讨论】:

      猜你喜欢
      • 2012-06-20
      • 1970-01-01
      • 2021-05-01
      • 2016-02-04
      • 2022-01-13
      • 1970-01-01
      • 2016-11-16
      • 2017-11-02
      • 1970-01-01
      相关资源
      最近更新 更多