2017-03-29 111 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')]}}}