【问题标题】:Merge dictionaries without overwriting previous value where value is a list合并字典而不覆盖以前的值,其中值是一个列表
【发布时间】:2013-12-11 17:47:29
【问题描述】:

我知道Merge dictionaries without overwriting valuesmerging "several" python dictionariesHow to merge multiple dicts with same key?How to merge two Python dictionaries in a single expression?

不过,我的问题略有不同。

假设我有这三个字典

dict_a = {'a': [3.212], 'b': [0.0]}
dict_b = {'a': [923.22, 3.212], 'c': [123.32]}
dict_c = {'b': [0.0]}

合并后的结果应该是

result_dict = {'a': [3.212, 3.212, 923.22], 'b': [0.0, 0.0], 'c': [123.32]}

这里的代码有效,但会在列表中嵌套列表

result_dict = {}
dicts = [dict_a, dict_b, dict_c]

for d in dicts:
    for k, v in d.iteritems():
        result_dict.setdefault(k, []).append(v)

使用extend 而不是append 会阻止嵌套列表,但如果键不存在则不起作用。所以基本上它应该在没有覆盖的情况下执行update,就像在其他线程中一样。

对不起,这是我这边的一个错误。昨天太晚了,我没有注意到引发错误的那一行不是我认为的那一行,因此假设我的字典已经具有上述结构。 事实上,mgilson 是正确的,假设它与 TypeError 相关。确切地说,是一个“可组合的浮点数”。

【问题讨论】:

  • 您能解释一下为什么extend 不起作用吗? setdefault(k, [])不应该处理不存在的关键问题吗?
  • 为什么a 的结果列表以该顺序结束?我原以为:[ 3.212, 923.22, 3.212]
  • @mgilson 是的,对不起。我已经在脑子里整理好了。但应该是你说的那样。

标签: python dictionary merge


【解决方案1】:

我很确定 .extend 在这里工作......

>>> dict_a = {'a': [3.212], 'b': [0.0]}
>>> dict_b = {'a': [923.22, 3.212], 'c': [123.32]}
>>> dict_c = {'b': [0.0]}
>>> result_dict = {}
>>> dicts = [dict_a, dict_b, dict_c]
>>> 
>>> for d in dicts:
...     for k, v in d.iteritems():
...         result_dict.setdefault(k, []).extend(v)
... 
>>> result_dict
{'a': [3.212, 923.22, 3.212], 'c': [123.32], 'b': [0.0, 0.0]}

神奇之处在于dict.setdefault 方法。如果该键不存在,setdefault添加一个具有您提供的默认值的新键。然后它返回那个可以修改的默认值。


请注意,如果项目 v 不可迭代,此解决方案会有问题。也许这就是你的意思?例如如果dict_a = {'a': [3.212], 'b': 0.0}

在这种情况下,我认为您需要在try-except 子句中使用TypeError: type object is not iterable

for d in dicts:
    for k, v in d.iteritems():
        try:
            result_dict.setdefault(k, []).extend(v)
        except TypeError:
            result_dict[k].append(v)

【讨论】:

  • 我没有关注abc 中的所有内容。有没有什么基本上是“标量”的,即“不可迭代,或可迭代但字符串”?
  • @DSM -- 不确定我是否有问题。不确定我是否收到了 OP 的问题。 OP 的示例输入中的所有内容都是可迭代的,但 OP 表示 .extend 出于某种原因无法正常工作,这让我认为 OP 已经尝试过(尽管可能没有)。因此,我开始理解 为什么 .extend 可能失败的原因。一个不可迭代的项目似乎是最有可能的罪魁祸首......(但只是一个猜测)。
  • 我的意思是 TypeError 方法不会阻止标量但可迭代的对象(例如字符串)采用.extend 分支并将"Fred" 转换为"F", "r", "e", "d"
  • 啊...您是在引用str 没有.__iter__ 功能的事实?幸运的是 python3.x 解决了这个问题......我认为字符串是唯一通常被视为标量的对象,也是可迭代的......
  • 伙计,我没有很好地解释自己。 :^) 没有 python 3 连接,只是这段代码适用于标量数值,但不适用于标量字符串,我想知道除了 not isinstance(v, basestring) 之外是否还有一些聪明的技巧,我是最后一个听到的大约,像往常一样。
猜你喜欢
  • 1970-01-01
  • 2023-01-19
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多