Python prüft, ob eine Liste der Schlüssel im Wörterbuch vorhanden ist

86

Ich habe ein Wörterbuch, das so aussieht:

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

und eine Liste von Namen students = ('alex', 'john')

Ich muss überprüfen, ob alle Namen in studentsals Schlüssel in gradesdikt existieren.

gradeskann mehr Namen haben, aber alle Namen in studentssollten in seingrades

Es muss einen einfachen Weg geben, aber ich bin noch neu in Python und kann es nicht herausfinden. versucht if students in grades, hat nicht funktioniert.

In den tatsächlichen Fällen werden die Listen viel größer sein.

Apfeltuch
quelle

Antworten:

194

Verwendung all():

if all(name in grades for name in students):
    # whatever
Sven Marnach
quelle
Toll! Gibt es eine Abkürzung, um die Elemente zu erhalten, die im DIC fehlen, wenn die Bedingung False ist?
Guival
2
@guival Ja, Sie können Set-Operationen verwenden, z. B. set(students) - grades.keys()in Python 3.
Sven Marnach
Gibt es eine Möglichkeit zu überprüfen, ob eine Liste von Schlüsseln eine Unterzeichenfolge in einer Zeichenfolge ist?
Jonathan
@ Jonathan Nicht sicher, was du meinst, vielleicht any(k in my_string for k in keys)?
Sven Marnach
@SvenMarnach hat gerade any () entdeckt! Genau das habe ich gesucht :)
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

Der Aufruf classist ungültig, daher habe ich ihn geändert names.

Jamylak
quelle
Dies kann im Gegensatz zu nicht verkürzt werden all(). Es wird immer O (m + n) sein, wobei m und n die jeweiligen Größen von namesund sind grades. Die Verwendung all()ist O (m) und kann eine Abkürzung sein.
Sven Marnach
7
@SvenMarnach Richtig, ich lasse es einfach hier, da es ein anderer Ansatz ist, aber ich stimme zu, dass Ihr Ansatz der beste ist.
Jamylak
Lass es auf jeden Fall hier! Es ist auf jeden Fall ein interessanter Ansatz.
Sven Marnach
3

Angenommen, die Schüler sind festgelegt

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

Wenn nicht, konvertieren Sie es in set

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

Sie können testen, ob sich mehrere Schlüssel in einem Diktat befinden, indem Sie den Vorteil nutzen, dass <dict>.keys()a zurückgegeben wird set.

Diese Logik im Code ...

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

kann kurz dargestellt werden als:

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

Der <=Operator für Mengen prüft, ob die Menge auf der linken Seite eine Teilmenge der Menge auf der rechten Seite ist. Eine andere Art, dies zu schreiben, wäre <set>.issubset(other).

Es gibt andere interessante Operationen, die von Sets unterstützt werden: https://docs.python.org/3.8/library/stdtypes.html#set

Mit diesem Trick können viele Stellen im Code komprimiert werden, die nach mehreren Schlüsseln suchen, wie im ersten Beispiel oben gezeigt.

Ganze Schlüssellisten können auch auf Folgendes überprüft werden <=:

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

Oder wenn studentses auch ein Diktat ist:

if students.keys() <= grades.keys():
    ...
Todd
quelle