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

Например:

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

bool() возвращает True, поскольку это не просто пустой диктат.

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

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
-1
Jay 6 Фев 2020 в 03:49

2 ответа

Лучший ответ

Так же, как пояснение, этот метод работает для вложенной структуры 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, ''.

1
Hymns For Disco 6 Фев 2020 в 01:27

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

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

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

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

if (not get_val(v)):
    return False

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

0
JST99 6 Фев 2020 в 01:34