【问题标题】:Convert dict with mixed values to flat dict将混合值的字典转换为平面字典
【发布时间】:2016-08-03 15:31:09
【问题描述】:

我想遍历一个字典,它的值是列表、Unicode 字符串、字典、布尔值和整数的混合,以生成一个包含所有键值对的一维字典。我不在乎保留关联值为字典的键。

我尝试了递归函数,但缺少一些步骤。也许我需要在某处使用.update()+=

def unravel(data):
    resultsdict = {}
    for k in data:
        if isinstance(data[k],dict):
            unravel(data[k])
        else:
            resultsdict[k] = data[k]  

我的顶级字典值示例:

<type 'list'>
<type 'bool'>
<type 'dict'>
<type 'unicode'>
<type 'bool'>
<type 'unicode'>
<type 'dict'>
<type 'int'>
<type 'unicode'>

【问题讨论】:

  • 似乎每次你深入研究这个递归函数时,你都在用 resultsdict = {} 重置字典。我认为这可能是个问题?
  • 因此,对于包含在您的 dict 中的每个其他 dict,您想将该 dict 的内容移动到结构的根级别吗?例如。 { 'a': { 'b': 'c'}, 'd': 'e' } 变成 { 'b': 'c', 'd': 'e' }?
  • @poke 你是对的
  • @Adib 也正确,也许我应该使用yield

标签: python recursion iteration


【解决方案1】:

您可以解压所有字典元组,然后将整个内容展平

# Turn every key,value pair into a list of tuples 
# [(key, value)] if it's any datatype but dict
# value.iteritems() otherwise
grouped_key_value_pairs = [v.iteritems() if isinstance(v,dict) else [(k,v)] for k,v in data.iteritems()]

# Flatten into a single list of tuples and turn into dict!
result = dict([kv_pair for group in all_kv_pairs for kv_pair in group])

【讨论】:

  • 添加了一些 cmets 来提供帮助,但我确实认为这是一个非常密集的列表理解
  • 我确实喜欢一个很好的单线...我一定会把你的解决方案放在我的银行里
【解决方案2】:

您快到了,但您需要返回创建的字典,并使用递归调用的返回值更新字典:

def unravel (data):
    d = {}
    for k, v in data.items():
        if isinstance(v, dict):
            d.update(unravel(v))
        else:
            d[k] = v
    return d

这样使用:

>>> unravel({ 'a': { 'b': 'c', 'd': 'e' }, 'f': 'g', 'h': { 'i': 'j' } })
{'f': 'g', 'i': 'j', 'b': 'c', 'd': 'e'}

【讨论】:

    【解决方案3】:

    您的方法unravel 每次递归调用它时都会创建一个resultsdict 的新实例。因此,并非所有数据都进入主词典(可以这么说)。试试这样的:

    def unravel(data, resultsdict={}):
        for k in data:
            if isinstance(data[k],dict):
                unravel(data[k], resultsdict)
            else:
                resultsdict[k] = data[k]
        return resultsdict
    

    在这样的递归场景中,您应该在每次递归时随身携带可变数据结构。

    【讨论】:

    • 请避免使用mutable default arguments,即使您实际上并未在此处对其进行变异。
    • 实际上,我没有看到那个编辑。现在它只是坏了。尝试unravel({'a': 'b'}),后跟unravel({'b': 'c'})。后者现在将返回{'a': 'b', 'b': 'c'}
    • 我喜欢你的解决方案:D
    • 不客气。很高兴您选择了 poke 的答案。它就在:)
    猜你喜欢
    • 2011-12-08
    • 2016-06-16
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 2021-12-29
    • 2019-09-13
    • 2018-08-21
    • 1970-01-01
    相关资源
    最近更新 更多