Удалите пустые строковые ключи из вложенного словаря. - PullRequest
2 голосов
/ 28 апреля 2019

Это работает:

def delete_empty_keys(d):

    new_d = {}
    for key,value in d.items():
        if key != '' and not isinstance(value, dict):
            new_d[key] = value
        elif key != '' and isinstance(value, dict):
            new_d[key] = delete_empty_keys(value)
        else:
            pass
    return new_d

Как мне превратить это в понимание слова?Я пробовал это, но я не могу заставить его работать, у меня должен быть else pass в конце.

def delete_empty_keys(d):
    return {key: value
    if key != '' and not isinstance(value, dict)
    else delete_empty_keys(value)
    if key != '' and isinstance(value, dict)
    #else pass??
    for key, value in d.items()
    }

Ответы [ 2 ]

3 голосов
/ 28 апреля 2019

Ваша петля

for key,value in d.items():
    if key != '' and not isinstance(value, dict):
        new_d[key] = value
    elif key != '' and isinstance(value, dict):
        new_d[key] = delete_empty_keys(value)
    else:
        pass

на самом деле просто проверяет, должен ли ключ быть пропущен, или , если это не так, как обрабатывать значение. Если вы извлекаете тест ключа в отдельный оператор if, его можно переписать как

for key, value in d.items():
    if key != '':
        if not isinstance(value, dict):
            new_d[key] = value
        else:
            new_d[key] = delete_empty_keys(value)

Таким образом, тест if key != '': на самом деле фильтрует элементы, выбирая которые должны быть частью нового словаря. Фильтрация в понимании выполняется с помощью дополнительных if компонентов в цикле:

<item> for <target> in <iterable> if <test>  # optional: more for loops and if tests

Часть if <test> фильтрует итерируемое, ограничивая используемые элементы. Используйте то же самое в словарном понимании.

Это оставляет внутренний if...else тест, который можно выразить условным выражением (выбирая между двумя вариантами):

# iteration, for <target> in <iterable>
for key, value in d.items():
    # filter, if <test>
    if key != '':
        # <item>, here a <key> and <value> expression for the dict comprehension
        new_d[key] = value if not isinstance(value, dict) else delete_empty_keys(value)

Теперь у вас есть форма, которую можно превратить в словарь:

{
    key: value if not isinstance(value, dict) else delete_empty_keys(value)
    for key, value in d.items()
    if key != ''
}

или, в вашей функции:

def delete_empty_keys(d):
    return {key: value if not isinstance(value, dict) else delete_empty_keys(value)
            for key, value in d.items() if key != ''}
1 голос
/ 28 апреля 2019

Ну, если вы действительно хотите сделать это:

def delete_empty_keys(d):
    return {k: delete_empty_keys(v) if isinstance(v, dict) 
            else v 
            for k, v in d.items() if k != ''}

Пример:

d = {'': 'delete_me',
     'a': {'': {'delete': 'me',
                'me': 'too'},
           'dont': 'delete_me',
           'keep': 'me'},
     'b': {'': 'bye'},
     'c': 'not_nested'}

delete_empty_keys(d)

Вывод:

{'a': {'dont': 'delete_me', 'keep': 'me'}, 'b': {}, 'c': 'not_nested'}

Вы не pass в dict пониманиях, потому что pass ничего не возвращает.Все в понимании должно что-то возвращать.

Также, как отмечено в комментарии: None != ''.

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