Соответствие нескольким словарным ключам в большом масштабе в python - PullRequest
0 голосов
/ 20 марта 2020

Итак, в моей программе есть словарь со значениями, которые сильно меняются.

example_dict = {'a': True, 'b' : "b", 'c' : "c", 'd' : "d", 'e' : False, 'f' : {'fa' : "", 'fb' : "b", 'fc' : "fc", "fd" : 0, "fe" : 0, "ff" : 0, "fg" : []}}

У меня есть некоторые условные выражения, которые должны проверить, что набор некоторых из этих ключей (не всех) совпадает.

Что работает, если мне нужно проверить несколько условий, так это использовать 'и'.

if example_dict['a'] == True and example_dict['b'] == "b" and example_dict['c'] == "c" or example_dict['a'] == False and example_dict['b'] == "bb" and example_dict['c'] == "c":

В приведенном выше примере проверяется следующее, чтобы увидеть, существуют ли они в словаре примера:

{'a':True, 'b':"b", 'c':"c"}
{'a':False, 'b':"bb", 'c':"c"}

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

Ответы [ 4 ]

1 голос
/ 20 марта 2020

Итератор all может быть полезен здесь. Поместите ваши условия теста в массив, а затем используйте понимание списка, чтобы получить результат.

conditions = [('a', True), ('b', 'B'), ('c', 3)]
example_dict =  {'a': True, 'b': 'B', 'c': 3}
match = all(example_dict[k] == v for k, v in conditions)

РЕДАКТИРОВАТЬ: Добавить несколько наборов условий

Для проверки наборов условий добавьте any.

# Declare sets of conditions to test
conditions = [[('a', True), ('b', 'B')],
              [('a', True), ('c', 3)],
              [('a', True), ('c', 34)]]

# An example dictionary to test
example_dict =  {'a': True, 'b': 'B', 'c': 3}

# Test if any of the condition sets match.  The any iterator will
# return True at the first matching set of conditions.  The all
# iterator will compare each key and value within a set of conditions.
match = any(all(example_dict[k] == v for k, v in c) for c in conditions)
1 голос
/ 20 марта 2020

Вот возможное решение:

def dict_agree(req, d):
    return all([v == d[k] for k, v in req.items()])


# Demonstration

example_dict = {'a': True, 'b' : "b", 'c' : "c", 'd' : "d", 'e' : False,
'f' : {'fa' : "", 'fb' : "b", 'fc' : "fc", "fd" : 0, "fe" : 0, "ff" : 0, "fg" : []}}

requirement_dict_1 = {'a': False, 'b': 'b', 'c': 'c'}
requirement_dict_2 = {'a': True, 'b': 'b', 'c': 'c'}

print(dict_agree(requirement_dict_1, example_dict)) # False, because 'a' has the wrong value
print(dict_agree(requirement_dict_1, example_dict)) # True, all the requirements are satisfied
0 голосов
/ 21 марта 2020

Хорошо, я отвечаю на свой вопрос, потому что я внедряю гибрид двух, если кто-то читает это позже. Это код, который, кажется, работает для меня:

def main():
    # Dictionary to check
    example_dict = {'a': True, 'b' : "b", 'c' : "c", 'd' : "d", 'e' : False, 'f' : {'fa' : "", 'fb' : "b", 'fc' : "fc", "fd" : 0, "fe" : 0, "ff" : 0, "fg" : []}}
    # Conditions to find within the dictionary
    conditions = [[('a', True), ('b', "b"), ('c', "c")], [('a', False), ('b', "bb"), ('c', "c")]]
    # If the conditions aren't met, print false, else true
    if not check_conditions(example_dict, conditions):
        print("FALSE: a: {} b: {} c: {}".format(example_dict['a'], example_dict['b'], example_dict['c']))
    else:
        print("TRUE: a: {} b: {} c: {}".format(example_dict['a'], example_dict['b'], example_dict['c']))

# broken up into a function because my program
# is broken up over multiple files
def check_conditions(my_dict, condition_list):
    return any(all(my_dict[k] == v for k, v in c) for c in condition_list)

Вывод со словарем как есть:

TRUE: a: True b: b c: c

Вывод, когда «b» заменяется на «bb» (в первом случае не выполняется условие «b», во втором - условие «a»):

FALSE: a: True b: bb c: c

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

Спасибо Вы, все, за вашу помощь.

0 голосов
/ 20 марта 2020

вы можете использовать:

cond =  {(True, 'b', 'c'), (False, 'bb', 'c')}
tuple(map(example_dict.get, ('a', 'b', 'c'))) in cond

это будет O (M) сложность времени, где M - количество ключей, которые вы хотите проверить

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