2017-05-19 102 views
1

爲了過濾來自空值的字典列表,我需要從字典中刪除〜30%的數據。迭代時通過鍵從字典中刪除元素

所以我這個代碼結束:

qr = query_result 
    for row in qr: 
     for key, value in row.items(): 
      if value ==' ' or value == None, value == '': 
       del row[key] 

但是,在執行過程中出現錯誤,在第一次嘗試中刪除:

RuntimeError: dictionary changed size during iteration

了一下計算器搜索後我找到了solution,涉及將所有刪除的值複製到單獨的列表中供以後刪除。

delete = [] 
for k,v in dict.items(): 
    if v%2 == 1: 
     delete.append(k) 
for i in delete: 
    del dict[i] 

這方法中,轉換成這樣的代碼爲我的情況下:

qr = query_result 
for row in qr: 
    delete = [] 
    for key, value in row.items(): 
     if value == ' ' or value == '' or value == None: 
      delete.append(key) 
    for i in delete: 
     del row[i] 

這也是從某些RuntimeError缺點。

因此,刪除環外應詞典foreach循環:

qr = query_result 
for row in qr: 
    delete = [] 
    for key, value in row.items(): 
     if value == ' ' or value == '' or value == None: 
      delete.append(key) 
for i in delete: 
    del row[i] 

但考慮到代碼,不幸的是,正確的修改只有最後一排。

如何處理所有行然後刪除垃圾數據?

下面是用於測試的一些數據:

c = [{'A': 'B', 'C': '3', 'EE': None, 'P': '343', 'AD': ' ', 'B': ''}, 
    {'A': 'B', 'C': '3', 'EE': None, 'P': '343', 'AD': ' ', 'B': ''}] 

我的輸出:

{'A': 'B', 'C': '3', 'EE': None, 'P': '343', 'AD': ' ', 'B': ''} 
{'A': 'B', 'C': '3', 'P': '343'} 

希望的輸出:

{'A': 'B', 'C': '3', 'P': '343'} 
{'A': 'B', 'C': '3', 'P': '343'} 

回答

0

一個班輪:

c = [{k: v for k, v in d.items() if v not in [' ', '', None]} for d in c] 

循環遍歷c的元素,然後每個元素只返回匹配的鍵值對。這將返回:

[{'A': 'B', 'P': '343', 'C': '3'}, {'A': 'B', 'P': '343', 'C': '3'}] 
2

這裏是一個版本,修改你的第一個例子,你需要「複製」你的清單,並在同一時間刪除迭代。在迭代複製列表之後,可以根據需要從原始列表中刪除。

import copy 

qr = [{'A': 'B', 'C': '3', 'EE': None, 'P': '343', 'AD': ' ', 'B': ''}, 
    {'A': 'B', 'C': '3', 'EE': None, 'P': '343', 'AD': ' ', 'B': ''}] 

for i, row in enumerate(copy.deepcopy(qr)): 
    for key, value in row.items(): 
     if value in {' ', None, ''}: 
      del qr[i][key] 

print(qr) 

除此之外,通常需要創建一個新列表,而不是從原始列表中刪除。一個簡單的列表解析會做的伎倆:

qr = [{k:v for k, v in row.items() if v not in {' ', None, ''}} for row in qr] 

print(qr) # same result 

輸出兩種:

[{'A': 'B', 'C': '3', 'P': '343'}, 
{'A': 'B', 'C': '3', 'P': '343'}] 
1

你的方法(領取鑰匙,而迭代,刪除之後)是正確的。

這是你的問題:

qr = query_result 
for row in qr: 
    delete = [] # <--- here 

你每次當您觸摸一個新行時間創建一個新的delete列表。如果從前一行中留下任何數據,則會丟失。

delete = [] # Only once for all rows. 
qr = query_result 
for row in qr: 
    # ... 

for k in delete: 
    del data[k] 

相反,你應該在同一水平(壓痕)爲隨後使用它創建