问题:
如何遍历字典并删除其中的ourtestuser@gmail.com
键或值?
这是我尝试过的:
代码:
None
输入:
import copy
def _ignore(data):
copied_data = copy.deepcopy(data)
print('-------------------------')
print(f'copied_data: {copied_data}')
print('-------------------------')
if isinstance(copied_data, list):
print(f'item is instance of list: {copied_data}')
for idx, item in enumerate(data):
if isinstance(item, list):
return _ignore(item)
elif isinstance(item, dict):
return _ignore(item)
elif item is None:
del copied_data[idx]
elif isinstance(copied_data, dict):
print(f'item is instance of dict: {copied_data}')
for key, item in data.items():
if isinstance(item, list):
return _ignore(item)
elif isinstance(item, dict):
return _ignore(item)
elif item is None:
del copied_data[key]
return copied_data
if __name__ == '__main__':
data = {'key1': None, 'key2': {'k1': None, 'k2': 2}, 'key3': [None, 1, 2, 3, 4]}
print(f'output: {_ignore(data=data)}')
输出:
{'key1': None, 'key2': {'k1': None, 'k2': 2}, 'key3': [None, 1, 2, 3, 4]}
请紧记,该代码还应删除嵌套
------------------------- copied_data: {'key1': None, 'key2': {'k1': None, 'k2': 2}, 'key3': [None, 1, 2, 3, 4]} ------------------------- item is instance of dict: {'key1': None, 'key2': {'k1': None, 'k2': 2}, 'key3': [None, 1, 2, 3, 4]} ------------------------- copied_data: {'k1': None, 'k2': 2} ------------------------- item is instance of dict: {'k1': None, 'k2': 2} output: {'k2': 2}
或嵌套None
中的list
个值,而我们不能从{ {1}},我们正在对其进行迭代。
更新:
该代码应支持嵌套的dict
或dict
这是另一个输入示例:
dict
谢谢。
答案 0 :(得分:1)
您可以递归检查并返回key, value
对,然后像这样从中创建一个新的dict
$ cat rmnone.py
data = {'key1': None, 'key2': {'k1': {'k3': [None, 1, 23], 'k4': None}, 'k2': 2},
'key3': [{'key1': None, 'key2': [None, 1, 2, 3], 'key3': {'k1': 1}}, 1, 2, 3, 4]}
def func(data):
for key, val in data.items():
if val is not None:
if isinstance(val, list):
tmp = []
for v in val:
if isinstance(v, dict):
for k,v in func(v):
tmp.append({k:v})
elif v is not None:
tmp.append(v)
yield (key, tmp)
if isinstance(val, tuple):
tmp = []
for v in val:
if isinstance(v, dict):
for k,v in func(v):
tmp.append({k:v})
elif v is not None:
tmp.append(v)
yield (key, tmp)
elif isinstance(val, dict):
tmp = {}
for k,v in func(val):
tmp.update({k:v})
yield key, tmp
elif not isinstance(val, (tuple, dict, list)):
yield key,val
d = {k:v for k,v in func(data)}
print(d)
输出:
$ python3 rmnone.py
{'key2': {'k1': {'k3': [1, 23]}, 'k2': 2}, 'key3': [{'key2': [1, 2, 3]}, {'key3': {'k1': 1}}, 1, 2, 3, 4]}
答案 1 :(得分:1)
这里是创建新对象的一种方法。
def removed_none(obj):
t = type(obj)
if issubclass(t, (tuple, list, set)):
obj = t(removed_none(a) for a in obj if a is not None)
elif issubclass(t, dict):
obj = {k: removed_none(v) for k, v in obj.items()
if k is not None and v is not None}
return obj
data = {'key1': None, 'key2': {'k1': None, 'k2': {1: 2, 3: None}},
'key3': [None, [1, None, 0], 2, 3, 4]}
print(f'output: {removed_none(data)}')
# output: {'key2': {'k2': {1: 2}}, 'key3': [[1, 0], 2, 3, 4]}
如果要在适当位置修改现有对象,则这里有一个不同的功能(remove_none
而不是removed_none
)。请注意,这不能用于修改包含None
值的元组,因为它们是不可变的。
def remove_none(obj):
if isinstance(obj, list):
for i in range(len(obj) - 1, -1, -1):
if obj[i] is None:
del obj[i]
else:
remove_none(obj[i])
elif isinstance(obj, set):
obj.discard(None)
for elem in obj:
remove_none(elem)
elif isinstance(obj, dict):
for k, v in list(obj.items()):
if k is None or v is None:
del obj[k]
else:
remove_none(v)
data = {'key1': None, 'key2': {'k1': None, 'k2': {1: 2, 3: None}},
'key3': [None, [1, None, 0], 2, 3, 4]}
remove_none(data)
print(f'output: {data}')
# output: {'key2': {'k2': {1: 2}}, 'key3': [[1, 0], 2, 3, 4]}
答案 2 :(得分:1)
您没有按照自己的意愿去做,因为据我所知,您仅删除了None
个值。该命令:
{'key1': None, 'key2': {'k1': None, 'k2': 2}, 'key3': [None, 1, 2, 3, 4]}
仅具有None
值,没有键。我要在这里坚持键和值的Python定义。 None
键如下:
{None: "value"}
但是,您可以轻松地执行以下操作:
def recursive_filter(item, *forbidden):
if isinstance(item, list):
return [recursive_filter(entry, *forbidden) for entry in item if entry not in forbidden]
if isinstance(item, dict):
result = {}
for key, value in item.items():
value = recursive_filter(value, *forbidden)
if key not in forbidden and value not in forbidden:
result[key] = value
return result
return item
您可以像这样使用:
clean = recursive_filter(dirty, None)
或者,如果您想过滤出更多内容:
clean = recursive_filter(dirty, *iterable_of_forbidden_things)
clean = recursive_filter(dirty, None, other_forbidden_thing)
如果您真的只在乎值,那么就可以删除对键的检查。
答案 3 :(得分:0)
这基本上已经完成了here,并且也以稍微修改的形式解决了该问题:
d = {'key1': None,
'key2': {'k1': None, 'k2': 2},
'key3': [None, 1, 2, 3, 4],
None: 42}
def scrub_none(node):
if isinstance(node, dict):
for k in list(node.keys()):
if node[k] is None or k is None:
del node[k]
else:
scrub_none(node[k])
elif isinstance(node, list):
for i in reversed(range(len(node))):
if node[i] is None:
del node[i]
else:
scrub_none(node[i])
else:
pass
scrub_none(d)
print(d)
# {'key2': {'k2': 2}, 'key3': [1, 2, 3, 4]}
注释#1:就地修改输入dict
注释#2:还会删除None
键(如果存在)