如何摆脱字典中的无值?

时间:2010-03-30 11:27:01

标签: python

类似的东西:

for (a,b) in kwargs.iteritems():
    if not b : del kwargs[a]

此代码引发异常,因为在迭代时更改字典。

我发现只有另一个字典的非常漂亮的解决方案:

res ={}
res.update((a,b) for a,b in kwargs.iteritems() if b is not None)

由于

6 个答案:

答案 0 :(得分:50)

另一种写作方式是

res = dict((k,v) for k,v in kwargs.iteritems() if v is not None)

在Python3中,这变为

res = {k:v for k,v in kwargs.items() if v is not None}

答案 1 :(得分:5)

我喜欢你的第二种方法的变化:

   res = dict((a, b) for (a, b) in kwargs.iteritems() if b is not None)

它是Pythonic,我认为不丑。你的第一个变体是:

   for (a, b) in list(kwargs.iteritems()):
       if b is None:
            del kwargs[a]

答案 2 :(得分:5)

您还可以使用filter

d = dict(a = 1, b = None, c = 3)

filtered = dict(filter(lambda item: item[1] is not None, d.items()))

print(filtered)
{'a': 1, 'c': 3}

答案 3 :(得分:3)

d = {'a': None, 'b': 'myname', 'c': 122}
print dict(filter(lambda x:x[1], d.items()))
{'b': 'myname', 'c': 122}

答案 4 :(得分:1)

如果您需要处理嵌套 dict,则可以利用一种简单的递归方法:

# Python 2
from collections import Mapping

def filter_none(d):
    if isinstance(d, Mapping):
        return dict((k, filter_none(v)) for k, v, in d.iteritems() if v is not None)
    else:
        return d

# Python 3
from collections.abc import Mapping

def filter_none(d):
    if isinstance(d, Mapping):
        return {k: filter_none(v) for k, v in d.items() if v is not None}
    else:
        return d

答案 5 :(得分:0)

对于任何可能感兴趣的人,这是摆脱无价值的另一种方法。我没有删除密钥,而是使用同一密钥的占位符更改了None的值。

一个用例是将Spark RDD.map应用于空值JSON。

def filter_null(data, placeholder="[spark]nonexists"):
    # Replace all `None` in the dict to the value of `placeholder`
    return dict((k, filter_null(v, placeholder) if isinstance(v, dict) else v if v 
is not None else placeholder) for k, v in data.iteritems())

示例输出:

>>> filter_null({'a':None,'b':"nul", "c": {'a':None,'b':"nul"}})
{'a': '[spark]nonexists', 'c': {'a': '[spark]nonexists', 'b': 'nul'}, 'b': 'nul'}

对于python3,将iteritems()更改为items()