将具有混合值的dict转换为flat dict

时间:2016-04-12 20:09:24

标签: python recursion iteration

我想遍历一个dict,其值是列表,unicode字符串,dicts,bools和int的混合,以生成具有所有键值对的一维字典。我不关心保存关联值为dicts的键。

我尝试了一个递归函数,但我错过了一些步骤。也许我需要在某个地方使用.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'>

3 个答案:

答案 0 :(得分:4)

你几乎就在那里,你需要返回创建的字典,并使用递归调用返回的值更新字典:

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'}

答案 1 :(得分:1)

每次递归调用时,您的方法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

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

答案 2 :(得分:0)

你可以解压缩所有字典元组,然后展平整个事物

# 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])