简体   繁体   English

Python迭代嵌套字典以删除键

[英]Python iterate nested dictionary to remove keys

I want to remove nested keys in a dictionary whose values are empty. 我想删除值为空的字典中的嵌套键。

Example: 例:

d = {'A': {'a': {1: [('string1', 'string2')]}}, 
     'B': {'b': {}},
     'C': {}
    }

For each of the main keys, there is a sub key and a sub sub key. 对于每个主键,都有一个子键和一个子子键。 If any of the key's values are empty, i want to remove the entire key. 如果任何键的值为空,我想删除整个键。

However, i get the error : RuntimeError: dictionary changed size during iteration when i loop through the dictionary to delete empty values. 但是,当我循环遍历字典以删除空值时,出现错误: RuntimeError: dictionary changed size during iteration

for k,v in d.iteritems():
    if not v:
        del d[k]
    else:
        for a,b in v.iteritems():
        if not b:
            del d[k][a]

desired output: 所需的输出:

d = {'A': {'a': {1: [('string1', 'string2')]}}}

As others have pointed out, you're modifying the iterable as you iterate over it. 正如其他人指出的那样,您在迭代时正在修改可迭代。 Instead, you could make a deep copy of your dictionary to iterate over, which will allow you to edit the contents of the original datastructure. 相反,您可以复制字典的深层副本以进行遍历,这将使您可以编辑原始数据结构的内容。

import copy
d = {'A': {'a': {1: [('string1', 'string2')]}},
     'B': {'b': {}},
     'C': {}
    }

for k,v in copy.deepcopy(d).items():
    if not v:
        del d[k]
    else:
        for a,b in v.items():
            if not b:
                del d[k]

out: 出:

{'A': {'a': {1: [('string1', 'string2')]}}}

You can create the identical deep copy of your dictionary. 您可以创建字典的相同深层副本。 Below is the solution for the same. 下面是相同的解决方案。

import copy
d = {'A': {'a': {1: [('string1', 'string2')]}}, 
     'B': {'b': {}},
     'C': {}
    }

d2 = copy.deepcopy(d)

for k,v in d.items():
    if not v:
        del d2[k]
    else:
        for a,b in v.items():
            if not b:
                del d2[k][a]
        if not d2[k]:
            del d2[k]
print(d2)

So, d2 gives you require dict. 因此,d2给您要求字典。

for k, v in d.items():

  if not v:
    del d[k]
  else:
    for a,b in v.items():
        if not b:
            if len(d[k])==1:
                del d[k][a]
                del d[k]
            else:
                del d[k][a]
print d

here is fix to your problem 这是解决您的问题的方法

old_d = {'A': {'a': {1: [('string1', 'string2')]}}, 
 'B': {'b': {}},
 'C': {}
}

new_d ={}

for k,v in old_d.iteritems():
print k
print v
if v:
    for a,b in v.iteritems():
        if b:
            new_d[k]=v
            new_d[k][a]=b
old_d = new_d
print "old_d", old_d

output: old_d {'A': {'a': {1: [('string1', 'string2')]}}} 输出: old_d {'A': {'a': {1: [('string1', 'string2')]}}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM