Проверьте, не содержит ли словарь значений для всех ключей - PullRequest
0 голосов
/ 06 февраля 2020

Каков наилучший способ проверить, что во вложенном словаре нет значений для всех ключей?

Например:

dict = {
    'var1': [],
    'var2': {
        'var3': [],
        'var4': {}
    },
    'var5': {}
}

bool() возвращает True, поскольку он не является строго empty dict.

Это возможно с помощью рекурсии, но мне любопытно, есть ли «лучшие» способы сделать это с точки зрения производительности, а также длины кода - возможно, с любыми функциями пакета.

def get_val(d):
    val = []
    for k,v in d.items():
        if (v):
            if (type(v) is dict):
                if (not get_val(v)):
                    return False
            else:
                return False
    return True

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Так же, как пояснение, этот метод работает для структуры вложенного композита ie dict / list, так как именно это вы показали в своем примере

def empty(d):
    if isinstance(d, dict):
        return all(empty(sub) for _, sub in d.items())
    if isinstance(d, list):
        return all(empty(sub) for sub in d)
    return False

Это, конечно, короче, но это все еще рекурсивно. Прохождение через произвольно вложенную структуру является изначально рекурсивной проблемой.

Кроме того, вы можете заметить, что эта функция устраняет любую зависимость от неявной bool сущности любых объектов. Причина в том, что хотя пустые list [] и пустые dict {} оцениваются как ложные, так и другие объекты, подобные нулю, например, 0, 0.0, ''.

0 голосов
/ 06 февраля 2020

Как указывает @Heap Overflow, список val не используется, и поэтому его не нужно объявлять.

Не могу сказать, что это заметное улучшение по сравнению с вашим кодом, но оно несколько упрощает и удаляет синтаксис c sugar.

def is_empty(d):
    for key, val in d.items():
        if val:
            if isinstance(val, dict):
                return is_empty(val)
            return False
    return True

Хорошей практикой является упрощение кода убедившись, что ваши логические логики c не являются излишне запутанными. Хороший пример - фрагмент из вашего исходного исходного кода.

if (not get_val(v)):
    return False

Вместо двойного отрицания упростите, сделав все явным.

...