Python проверяет, существует ли список ключей в словаре

87

У меня есть словарь, который выглядит так:

grades = {
        'alex' : 11,
        'bob'  : 10,
        'john' : 14,
        'peter': 7
       }

и список имен students = ('alex', 'john')

Мне нужно проверить, что все имена studentsсуществуют как ключи в gradesdict.

gradesможет иметь больше имен, но все имена studentsдолжны быть вgrades

Должен быть простой способ сделать это, но я все еще новичок в python и не могу понять этого. пробовал if students in grades, не сработало.

В реальных случаях списки будут намного больше.

платок
источник

Ответы:

195

Использование all():

if all(name in grades for name in students):
    # whatever
Свен Марнах
источник
Большой! Любой быстрый способ получить элементы, отсутствующие в dic, если условие ложно?
guival
2
@guival Ага, вы можете использовать операции с наборами, например, set(students) - grades.keys()в Python 3.
Свен Марнах,
есть ли способ проверить, является ли какой-либо из списка ключей подстрокой в ​​строке?
Джонатан
@Jonathan Не уверен, что ты имеешь в виду any(k in my_string for k in keys)?
Свен Марнах,
@SvenMarnach обнаружил любой ()! Это именно то, что я искал :)
Джонатан,
22
>>> grades = {
        'alex' : 11,
        'bob'  : 10,
        'john' : 14,
        'peter': 7
}
>>> names = ('alex', 'john')
>>> set(names).issubset(grades)
True
>>> names = ('ben', 'tom')
>>> set(names).issubset(grades)
False

Вызов classнедопустим, поэтому я изменил его на names.

Джамылак
источник
Это не может сократить, в отличие от all(). Это всегда будет O (m + n), где m и n - соответствующие размеры namesи grades. Использование all()будет O (м) и может сократить.
Sven Marnach
7
@SvenMarnach Хорошо, я просто оставлю это здесь, так как это другой подход, но я согласен, что ваш лучший.
jamylak
Однозначно оставьте это здесь! В любом случае это интересный подход.
Sven Marnach
3

Принимая студентов как набор

if not (students - grades.keys()):
    print("All keys exist")

Если не преобразовать его в набор

if not (set(students) - grades.keys()):
    print("All keys exist")
абхилех
источник
0

Вы можете проверить, есть ли в dict несколько ключей, воспользовавшись преимуществом, которое <dict>.keys()возвращает set.

Эта логика в коде ...

if 'foo' in d and 'bar' in d and 'baz' in d:
    do_something()

можно более кратко представить как:

if {'foo', 'bar', 'baz'} <= d.keys():
    do_something()

<=Оператор для наборов тестов для того набора слева подмножество множества справа. Другой способ написать это <set>.issubset(other).

Есть и другие интересные операции, поддерживаемые наборами: https://docs.python.org/3.8/library/stdtypes.html#set

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

Также можно проверить целые списки ключей на предмет использования <=:

if set(students) <= grades.keys():
    print("All studends listed have grades in your class.")

# or using unpacking - which is actually faster than using set()
if {*students} <= grades.keys():
    ...

Или если studentsэто тоже диктат:

if students.keys() <= grades.keys():
    ...
Тодд
источник