2017-03-29 77 views
-1

我想删除字典值为空的嵌套键。Python迭代嵌套字典以删除键

实施例:

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

对于每个的主键,还有一个子密钥和子子密钥。 如果任何键值为空,我想删除整个键。

但是,我收到错误: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] 

所需的输出:

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

你不能从一个集合,同时通过它迭代删除项目。在迭代期间,您需要保留要在集合中删除条目的索引/引用,并在遍历整个字典后将其删除。 –

+1

错误很明显。在迭代时不要修改(特别是大小)迭代器。 – Kasramvd

+1

您正在修改迭代过的内容。最激动人心的事情就是创建一个包含你想要的东西的新数据结构。 – pvg

回答

1

正如其他人所指出的那样,你正在修改的迭代,你遍历它。相反,您可以创建一个字典的深层副本来迭代,这将允许您编辑原始数据结构的内容。

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] 

出来:

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

您可以创建你的字典的相同的深层副本。以下是同样的解决方案。

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) 

所以,d2给你需要字典。

0
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 
0

这里是解决你的问题

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 

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