用元组键展平嵌套词典

2024-09-28 22:25:38 发布

您现在位置:Python中文网/ 问答频道 /正文

如何将这个question推广到可能是元组的大小写键?你知道吗

即使是在所有字符串键的情况下,如果这些键累积到一个元组中,也不需要特殊分隔符(尽管JSON导出是另一回事):

一种方法是基于这个answer。我试过两个版本:

def flatten_keys(d,handler,prefix=[]):
    return {handler(prefix,k) if prefix else k : v
        for kk, vv in d.items()
        for k, v in flatten_keys(vv, handler, kk).items()
        } if isinstance(d, dict) else { prefix : d }

其中元组处理程序是:

def tuple_handler_1(prefix,k):
    return tuple([prefix]+[k])

def tuple_handler_2(prefix,k):
    return tuple(flatten_container((prefix,k)))

使用公用发电机:

def flatten_container(container):
    for i in container:
        if isinstance(i, (list,tuple)):
            for j in flatten_container(i):
                yield j
        else:
            yield i

考虑一个测试dict,但是使用元组键('hgf',1)

data =  {'abc':123, ('hgf',1):{'gh':432, 'yu':433}, 'gfd':902, 'xzxzxz':{"432":{'0b0b0b':231}, "43234":1321}}

两者都不能按预期工作:

flatten_keys(data,tuple_handler_1)

{'abc': 123, (('hgf', 1), 'gh'): 432, (('hgf', 1), 'yu'): 433, 'gfd': 902, ('xzxzxz', ('432', '0b0b0b')): 231, ('xzxzxz', '43234'): 1321}

('xzxzxz', ('432', '0b0b0b'))。不是扁平的

第二个将输入元组键展平

flatten_keys(data,tuple_handler_2)

{'abc': 123, ('hgf', 1, 'gh'): 432, ('hgf', 1, 'yu'): 433, 'gfd': 902, ('xzxzxz', '432', '0b0b0b'): 231, ('xzxzxz', '43234'): 1321}

flatten方法是否有明显的修改,可以正确地连接字符串和其他哈希表?你知道吗

编辑

根据下面的注释,使用此方法处理键冲突的问题是字符串键的基本情况所固有的,例如{'a_b':{'c':1}, 'a':{'b_c':2}}。你知道吗

因此,即使在forlen1密钥路径中,每个密钥路径都应该是一个be元组,以避免密钥冲突,例如{((1,2),): 3, (1,2):4}}。你知道吗


Tags: 方法字符串inforprefixreturncontainerdef
1条回答
网友
1楼 · 发布于 2024-09-28 22:25:38

假设您需要以下输入/输出

# input
{'abc': 123,
 ('hgf', 1): {'gh': 432, 'yu': 433},
 'gfd': 902,
 'xzxzxz': {'432': {'0b0b0b': 231}, '43234': 1321}}

# output
{('abc',): 123,
 (('hgf', 1), 'gh'): 432,
 (('hgf', 1), 'yu'): 433,
 ('gfd',): 902,
 ('xzxzxz', '432', '0b0b0b'): 231,
 ('xzxzxz', '43234'): 1321}

一种方法是在字典上递归,直到找到非字典值,并在递归过程中将当前键作为元组传递。你知道吗

def flatten_dict(deep_dict): 
    def do_flatten(deep_dict, current_key): 
        for key, value in deep_dict.items():
            # the key will be a flattened tuple
            # but the type of `key` is not touched
            new_key = current_key + (key,)
            # if we have a dict, we recurse
            if isinstance(value, dict): 
                yield from do_flatten(value, new_key) 
            else:
                yield (new_key, value) 
    return dict(do_flatten(deep_dict, ()))

相关问题 更多 >