Подтвердить что ты не робот

Как я могу избавиться от значений None в словаре?

Что-то вроде:

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)

Спасибо

4b9b3361

Ответ 1

Другой способ записать это

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}

Ответ 2

Вы также можете использовать 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

Мне нравится изменение вашего второго метода:

   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]

Ответ 4

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

Ответ 5

Если вам нужно обрабатывать вложенные 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

Ответ 6

Для всех, кого это может заинтересовать, вот еще один способ избавиться от None value. Вместо того, чтобы удалить ключ, я изменяю значение 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'}