【问题标题】:Iterate dict of dict in python efficiently/pythonic在python中有效地迭代dict的dict/pythonic
【发布时间】:2020-09-07 23:04:42
【问题描述】:

我有一个字典,其中包含元组列表。必须在另一个字典中迭代和更新。 例如:

input_dict = {'503334': {'InterRAT': [
                            ['10', 'PLMN-1', 'SIB'],
                            ['20', 'PLMN-2', 'SIB']],
                        'Intra': [
                            ['30', 'PLMN-1', 'SIB'],
                            ['40', 'PLMN-2', 'SIB']],
                        'Inter': [
                            ['50', 'PLMN-2', 'SIB'],
                            ['60', 'PLMN-1', 'SIB']]},
              '490847': {'InterRAT': [
                            ['10', 'PLMN-1', 'SIB'],
                            ['80', 'PLMN-2', 'SIB']],
                        'Intra': [
                            ['20', 'PLMN-1', 'SIB'],
                            ['30', 'PLMN-2', 'SIB']],
                        'Inter': [
                            ['50', 'PLMN-2', 'SIB'],
                            ['60', 'PLMN-1', 'SIB']]}}

预期是:(迭代dict并取元组列表中的第一项并放入List中)

{'503334': {'InterRAT': ['10', '20'], 
            'Intra': ['30', '40'], 
            'Inter': ['50', '60']}, 
 '490847': {'InterRAT': ['10', '80'],
            'Intra': ['20', '30'], 
            'Inter': ['50', '60']}}

下面是我的代码,

for key, attrs in input_dict.items():
    for type, attr_list in attrs.items():
        try:
            if type == 'Inter':
                output[key]['Inter'] = \
                    [nbr[0] for nbr in attr_list]
            elif type == 'Intra':
                output[key]['Intra'] = \
                    [nbr[0] for nbr in attr_list]
            else:
                output[key]['InterRAT'] = \
                    [nbr[0] for nbr in attr_list]
        except KeyError as e:
            print("Exception {}".format(e))
            continue

是否有任何有效的或 Pythonic 的方式来做到这一点。

【问题讨论】:

    标签: python-3.x dictionary iteration


    【解决方案1】:

    如果您想就地修改input_dict,您可以执行以下操作:

    for k1, v1 in input_dict.items():
        for k2, v2 in v1.items():
            v1[k2] = [l[0] for l in v2]
    
    print(input_dict)
    # {'503334': {'InterRAT': ['10', '20'], 'Intra': ['30', '40'], 'Inter': ['50', '60']}, '490847': {'InterRAT': ['10', '80'], 'Intra': ['20', '30'], 'Inter': ['50', '60']}}
    

    如果你想创建一个新对象,你可以做类似的,但你分配给新对象:

    output = {}
    for k1, v1 in input_dict.items():
        output[k1] = {}
        for k2, v2 in v1.items():
            output[k1][k2] = [l[0] for l in v2]
    
    print(output)
    # {'503334': {'InterRAT': ['10', '20'], 'Intra': ['30', '40'], 'Inter': ['50', '60']}, '490847': {'InterRAT': ['10', '80'], 'Intra': ['20', '30'], 'Inter': ['50', '60']}}
    

    这可以用推导式写在一条语句中:

    output = {
        k1: {k2: [l[0] for l in v2] for k2, v2 in v1.items()}
        for k1, v1 in input_dict.items()}
    

    除了避免不必要的 try/exceptif/elif/else 块之外,这与您的代码很接近。 我认为这是一个很远的Pythonic

    【讨论】: