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

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

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 ]

52 голосов
/ 30 марта 2010

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

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}
7 голосов
/ 30 марта 2010

Вы также можете использовать 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}
5 голосов
/ 30 марта 2010

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

   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 голосов
/ 10 июля 2014
d = {'a': None, 'b': 'myname', 'c': 122}
print dict(filter(lambda x:x[1], d.items()))
{'b': 'myname', 'c': 122}
1 голос
/ 22 февраля 2019

Если вам нужно обработать вложенных 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
0 голосов
/ 03 июля 2019

Для всех, кого это интересует, вот еще один способ избавиться от 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'}

Для python3 измените iteritems() на items().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...