2017-05-19 67 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] 

相反,你应该在同一水平(压痕)为随后使用它创建