2017-05-19 13 views
1

辞書のリストを空の値からフィルタリングするために、辞書からデータの約30%を削除する必要があります。反復中にキーで辞書から要素を削除

だから私はこのコードで終わるしました:

RuntimeError: dictionary changed size during iteration

のstackoverflowの検索のビット後:しかし

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

、実行中にエラーが最初の削除で試みがあります私は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に苦しんでもあります。

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] 

しかし、与えられたコードは、残念ながら、唯一の最後の行に正しく修正:

したがって、ループは外部辞書のforeachループでなければならない削除。

すべての行を処理してからガベージデータを削除するにはどうすればよいですか?

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

あなたのアプローチを(反復しながら、後で削除し、キーを収集)が正しいです。あなたは新しい行に触れるたびに新しいdeleteリストを作成

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

はここにあなたの問題です。前の行からデータが残っていると、そのデータは失われます。

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

for k in delete: 
    del data[k] 

代わりに、あなたは後でそれを使用するよう(インデント)同じレベルにそれを作成する必要があります

関連する問題