Python vérifie si une liste de clés existe dans le dictionnaire

87

J'ai un dictionnaire qui ressemble à ça:

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

et une liste de noms students = ('alex', 'john')

Je dois vérifier que tous les noms studentsexistent en tant que clés dans gradesdict.

gradespeut avoir plus de noms, mais tous les noms studentsdoivent être dansgrades

Il doit y avoir un moyen simple de le faire, mais je suis encore nouveau en python et je ne peux pas le comprendre. essayé if students in grades, n'a pas fonctionné.

Dans les cas réels, les listes seront beaucoup plus grandes.

applaudissement
la source

Réponses:

195

Utilisez all():

if all(name in grades for name in students):
    # whatever
Sven Marnach
la source
Génial! Un raccourci pour obtenir les éléments manquants dans le dic si la condition est False?
guival
2
@guival Yup, vous pouvez utiliser les opérations set, par exemple set(students) - grades.keys()en Python 3.
Sven Marnach
existe-t-il un moyen de vérifier si l'une des clés d'une liste de clés est une sous-chaîne dans une chaîne?
Jonathan
@Jonathan Vous ne savez pas ce que vous voulez dire, peut any(k in my_string for k in keys)- être ?
Sven Marnach
@SvenMarnach vient de découvrir n'importe quel ()! C'est exactement ce que je cherchais :)
Jonathan
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

L'appeler classn'est pas valide, je l'ai donc changé en names.

Jamylak
la source
Cela ne peut pas raccourcir, contrairement à all(). Ce sera toujours O (m + n), où m et n sont les tailles respectives de nameset grades. Utiliser all()sera O (m), et pourrait raccourcir.
Sven Marnach
7
@SvenMarnach D'accord, je vais juste le laisser ici car c'est une autre approche mais je suis d'accord que la vôtre est la meilleure.
jamylak
Laissez-le définitivement ici! C'est une approche intéressante en tout cas.
Sven Marnach
3

En supposant que les étudiants sont définis

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

Sinon, convertissez-le en ensemble

if not (set(students) - grades.keys()):
    print("All keys exist")
abhilekh
la source
0

Vous pouvez tester si un certain nombre de clés sont dans un dict en tirant parti de ce qui <dict>.keys()renvoie a set.

Cette logique dans le code ...

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

peut être représenté plus brièvement comme:

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

L' <=opérateur des ensembles teste si l'ensemble de gauche est un sous-ensemble de l'ensemble de droite. Une autre façon d'écrire ce serait <set>.issubset(other).

Il existe d'autres opérations intéressantes supportées par les ensembles: https://docs.python.org/3.8/library/stdtypes.html#set

L'utilisation de cette astuce peut condenser de nombreux endroits dans le code qui vérifient plusieurs clés, comme indiqué dans le premier exemple ci-dessus.

Des listes entières de clés peuvent également être vérifiées en utilisant <=:

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():
    ...

Ou si studentsc'est aussi un dict:

if students.keys() <= grades.keys():
    ...
Todd
la source