嵌套字典中的del元组键;避免运行时和类型错误

时间:2018-08-13 03:36:18

标签: python python-3.x dictionary nested typeerror

我已经从最初来自.xlsx工作表的pandas数据框中生成了一个大型的嵌套字典。通过此过程,我的excel工作表中的一些空白单元格被导入为“ nan”,并且值存储在元组中,该元组用作键。生成的字典如下所示:

d_nans = {'feature1': {('1', '2'): [{'item1':'value1', 'item2': 'value2'}], 
                        ('nan', 'nan'): [{'item3':'value3', 'item4': 'value4'}]},
          'feature2': {('3', '10'): [{'item5':'value5', 'item6': 'value6'}], 
                       ('nan', 'nan'): [{'item7':'value7', 'item8': 'value8'}], 
                       ('23', '40'): [{'item9':'value9', 'item10': 'value10'}]},
          'feature3': {('21', '5000'): [{'item51':'value51', 'item61': 'value61'}], 
                       ('nan', 'nan'): [{'item71':'value71', 'item81': 'value81'}], 
                       ('560', '2400'): [{'item19':'value19', 'item110': 'value110'}]}} 

我需要一种编辑字典的方法,以删除键具有值('nan','nan')的所有key:value对。我尝试过:

for key, value in d_nans.items():
    seq_id = key
    feature_type = value
    for key, value in feature_type.items():
        if type(key) == tuple:
            if key[0] == 'nan':
                del feature_type[key]

运行时错误:“字典在迭代过程中更改了大小”

我尝试使用How to solve dictionary changed size during iteration in Python

中的一些代码来解决
for key, value in d_nans.items():
    seq_id = key
    feature_type = value
    for key, value in feature_type.items():
        for sub_key in list(feature_type.keys()):
            if sub_key[0] == 'nan':
                del dict[sub_key]

但这给了我

TypeError: 'type' object does not support item deletion

任何建议将不胜感激!

2 个答案:

答案 0 :(得分:2)

您可以使用dict.pop删除特定的键(如果存在)。如果键不存在,请指定默认值以避免KeyError。由于您有嵌套的字典,因此可以使用for循环。

for v in d_nans.values():
    v.pop(('nan', 'nan'), None)

在迭代字典时修改字典通常不是一个好主意,但是由于您没有在父d_nans字典中删除/添加键,因此在这里不了解它。

现在让我们看看您的两次尝试:

  1. 您的第一次尝试失败,因为您的字典大小随迭代而改变。 docs中对此进行了明确的解释:
  

在添加或删除字典中的条目时迭代视图可能   引发RuntimeError或无法遍历所有条目。

  1. dict是类,而不是实例。因此,您不能使用del dict[key]。无论如何,按照您的第一次尝试,这不是一个好主意,但是仍然会失败。

答案 1 :(得分:1)

您不必检查内部字典(feature_type)是否存在('nan', 'nan'),而只需检查feature_type是否包含('nan', 'nan')'。这样,您可以避免两个错误。尝试以下代码:

for _, feature_type in d_nans.items():
    if ('nan', 'nan') in feature_type:
        del feature_type[('nan', 'nan')]

如果将示例输入到此循环中,d_nans将变为以下内容:

{'feature1': {('1', '2'): [{'item1': 'value1', 'item2': 'value2'}]},
'feature2': {('3', '10'): [{'item5': 'value5', 'item6': 'value6'}], ('23', '40'): [{'item9': 'value9', 'item10': 'value10'}]},
'feature3': {('21', '5000'): [{'item51': 'value51', 'item61': 'value61'}], ('560', '2400'): [{'item19': 'value19', 'item110': 'value110'}]}}