Remove element from dictionary by key while iterating
为了从空值中过滤字典列表,我需要从字典中删除大约30%的数据。
所以我得到了这个代码:
1 2 3 4 5 | qr = query_result for row in qr: for key, value in row.items(): if value ==' ' or value == None, value == '': del row[key] |
但是,在执行第一次删除尝试时出错:
在对stackoverflow进行了一点搜索之后,我找到了解决方案,它包括将所有已删除的值复制到单独的列表中,以便随后删除。
1 2 3 4 5 6 | delete = [] for k,v in dict.items(): if v%2 == 1: delete.append(k) for i in delete: del dict[i] |
号
对于我的案例,这种方法可以转换成这样的代码:
1 2 3 4 5 6 7 8 | 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] |
同时也受到某些
因此,删除循环应在dict foreach循环之外:
1 2 3 4 5 6 7 8 | 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] |
。
但不幸的是,给定的代码只能正确地修改最后一行。
如何处理所有行,然后删除垃圾数据?
以下是一些测试数据:
1 2 | c = [{'A': 'B', 'C': '3', 'EE': None, 'P': '343', 'AD': ' ', 'B': ''}, {'A': 'B', 'C': '3', 'EE': None, 'P': '343', 'AD': ' ', 'B': ''}] |
我的输出:
1 2 | {'A': 'B', 'C': '3', 'EE': None, 'P': '343', 'AD': ' ', 'B': ''} {'A': 'B', 'C': '3', 'P': '343'} |
。
期望输出:
1 2 | {'A': 'B', 'C': '3', 'P': '343'} {'A': 'B', 'C': '3', 'P': '343'} |
。
这里是一个修改您的第一个示例的版本,您需要"复制"您的列表以与它进行迭代并同时删除。在迭代复制的列表之后,可以根据需要从原始列表中删除。
1 2 3 4 5 6 7 8 9 10 11 | 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) |
除此之外,通常您希望创建一个新列表,而不是从原始列表中删除。一个简单的列表理解就可以做到这一点:
1 2 3 | qr = [{k:v for k, v in row.items() if v not in {' ', None, ''}} for row in qr] print(qr) # same result |
。
两者的输出:
1 2 | [{'A': 'B', 'C': '3', 'P': '343'}, {'A': 'B', 'C': '3', 'P': '343'}] |
您的方法(迭代时收集密钥,然后删除)是正确的。
这是你的问题:
1 2 3 | qr = query_result for row in qr: delete = [] # <--- here |
。
每次触摸新行时,都会创建一个新的
相反,您应该在随后使用它的同一级别(缩进)上创建它:
1 2 3 4 5 6 7 | delete = [] # Only once for all rows. qr = query_result for row in qr: # ... for k in delete: del data[k] |
。
一条直线:
1 | c = [{k: v for k, v in d.items() if v not in [' ', '', None]} for d in c] |
循环遍历EDOCX1的元素(0),然后对于每个元素只返回匹配的键值对。这将返回:
1 | [{'A': 'B', 'P': '343', 'C': '3'}, {'A': 'B', 'P': '343', 'C': '3'}] |
号