Python sprawdza, czy lista kluczy istnieje w słowniku

87

Mam słownik, który wygląda tak:

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

i listę nazwisk students = ('alex', 'john')

Muszę sprawdzić, czy wszystkie nazwy są w studentsdyktandzie jako klucze grades.

gradesmoże mieć więcej nazw, ale wszystkie nazwy w sekcji studentspowinny znajdować się wgrades

Musi istnieć prosty sposób, aby to zrobić, ale wciąż jestem nowy w Pythonie i nie mogę tego rozgryźć. próbował if students in grades, nie działa.

W rzeczywistości listy będą znacznie większe.

applechief
źródło

Odpowiedzi:

195

Zastosowanie all():

if all(name in grades for name in students):
    # whatever
Sven Marnach
źródło
Świetny! Czy jest jakiś skrót, aby uzyskać elementy, których brakuje z karty, jeśli warunek jest fałszywy?
guival
2
@guival Tak, możesz użyć operacji na zestawach, np. set(students) - grades.keys()w Pythonie 3.
Sven Marnach
czy istnieje sposób sprawdzenia, czy którykolwiek z kluczy jest podłańcuchem w ciągu?
Jonathan,
@Jonathan Może nie wiesz, co masz na myśli any(k in my_string for k in keys)?
Sven Marnach,
@SvenMarnach właśnie odkrył ()! Dokładnie tego szukałem :)
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

Nazywanie go classjest nieprawidłowe, więc zmieniłem go na names.

jamylak
źródło
W przeciwieństwie do all(). Zawsze będzie to O (m + n), gdzie m i n są odpowiednimi rozmiarami namesi grades. Użycie all()będzie O (m) i może być skrótem.
Sven Marnach
7
@SvenMarnach Racja, zostawię to tutaj, ponieważ jest to inne podejście, ale zgadzam się, że twoje jest najlepsze.
jamylak
Zdecydowanie zostaw to tutaj! W każdym razie to interesujące podejście.
Sven Marnach
3

Zakładając, że studenci są zbiorem

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

Jeśli nie, przekonwertuj go na zestaw

if not (set(students) - grades.keys()):
    print("All keys exist")
abhilekh
źródło
0

Możesz sprawdzić, czy w dyktandzie znajduje się kilka kluczy, korzystając z funkcji, która <dict>.keys()zwraca plik set.

Ta logika w kodzie ...

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

można przedstawić krócej jako:

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

<=Operator do testów zestawów do zestawu czy po lewej stronie jest podzbiorem zbioru po prawej stronie. Inaczej można by to napisać <set>.issubset(other).

Istnieją inne interesujące operacje obsługiwane przez zestawy: https://docs.python.org/3.8/library/stdtypes.html#set

Użycie tej sztuczki może skondensować wiele miejsc w kodzie, które sprawdzają kilka kluczy, jak pokazano w pierwszym przykładzie powyżej.

Można również sprawdzić całe listy kluczy pod kątem użycia <=:

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

Lub jeśli studentsjest to również dykt:

if students.keys() <= grades.keys():
    ...
Todd
źródło