Python:如何从嵌套数据结构(列表和字典)中递归删除 None 值? [英] Python: How RECURSIVELY remove None values from a NESTED data structure (lists and dictionaries)?

查看:36
本文介绍了Python:如何从嵌套数据结构(列表和字典)中递归删除 None 值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一些嵌套数据,包括列表、元组和字典:

Here is some nested data, that includes lists, tuples, and dictionaries:

data1 = ( 501, (None, 999), None, (None), 504 )
data2 = { 1:601, 2:None, None:603, 'four':'sixty' }
data3 = OrderedDict( [(None, 401), (12, 402), (13, None), (14, data2)] )
data = [ [None, 22, tuple([None]), (None,None), None], ( (None, 202), {None:301, 32:302, 33:data1}, data3 ) ]

目标:删除所有为 None 的键或值(从数据"中).如果列表或字典包含一个值,它本身就是一个列表、元组或字典,然后使用 RECURSE 来删除 NESTED Nones.

Goal: Remove any keys or values (from "data") that are None. If a list or dictionary contains a value, that is itself a list, tuple, or dictionary, then RECURSE, to remove NESTED Nones.

所需的输出:

[[22, (), ()], ((202,), {32: 302, 33: (501, (999,), 504)}, OrderedDict([(12, 402), (14, {'four': 'sixty', 1: 601})]))]

或更易读,这里是格式化输出:

Or more readably, here is formatted output:

StripNones(data)= list:
. [22, (), ()]
. tuple:
. . (202,)
. . {32: 302, 33: (501, (999,), 504)}
. . OrderedDict([(12, 402), (14, {'four': 'sixty', 1: 601})])

我会提出一个可能的答案,因为我还没有找到现有的解决方案.我感谢任何替代方案,或指向预先存在的解决方案的指针.

I will propose a possible answer, as I have not found an existing solution to this. I appreciate any alternatives, or pointers to pre-existing solutions.

编辑我忘了提到这必须在 Python 2.7 中工作.我目前无法使用 Python 3.

EDIT I forgot to mention that this has to work in Python 2.7. I can't use Python 3 at this time.

尽管值得为其他人发布 Python 3 解决方案.所以请指出您正在回答哪个python.

Though it IS worth posting Python 3 solutions, for others. So please indicate which python you are answering for.

推荐答案

如果您可以假设各个子类的 __init__ 方法具有与典型基类相同的签名:

If you can assume that the __init__ methods of the various subclasses have the same signature as the typical base class:

def remove_none(obj):
  if isinstance(obj, (list, tuple, set)):
    return type(obj)(remove_none(x) for x in obj if x is not None)
  elif isinstance(obj, dict):
    return type(obj)((remove_none(k), remove_none(v))
      for k, v in obj.items() if k is not None and v is not None)
  else:
    return obj

from collections import OrderedDict
data1 = ( 501, (None, 999), None, (None), 504 )
data2 = { 1:601, 2:None, None:603, 'four':'sixty' }
data3 = OrderedDict( [(None, 401), (12, 402), (13, None), (14, data2)] )
data = [ [None, 22, tuple([None]), (None,None), None], ( (None, 202), {None:301, 32:302, 33:data1}, data3 ) ]
print remove_none(data)

请注意,这 不会defaultdict 一起使用,例如因为 defaultdict 接受 __init__ 的附加参数.要使其与 defaultdict 一起使用,需要另一个特殊情况 elif(在常规 dicts 之前).

Note that this won't work with a defaultdict for example since the defaultdict takes and additional argument to __init__. To make it work with defaultdict would require another special case elif (before the one for regular dicts).

另请注意,我实际上构建了对象.我没有修改旧的.如果您不需要支持修改像 tuple 这样的不可变对象,则可以修改旧对象.

Also note that I've actually constructed new objects. I haven't modified the old ones. It would be possible to modify the old objects if you didn't need to support modifying immutable objects like tuple.

这篇关于Python:如何从嵌套数据结构(列表和字典)中递归删除 None 值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆