Jak sprawdzić, czy coś jest (nie) na liście w Pythonie?
Najtańszym i najbardziej czytelnym rozwiązaniem jest użycie inoperatora (lub w konkretnym przypadku not in). Jak wspomniano w dokumentacji,
Operatorzy ini not intest na członkostwo. x in socenia,
Trueczy xjest członkiem si w Falseinny sposób. x not in szwraca negację x in s.
Dodatkowo,
Operator not inma zdefiniowaną odwrotną wartość rzeczywistą wynoszącą in.
y not in xjest logicznie taki sam jak not y in x.
Oto kilka przykładów:
'a' in [1, 2, 3]
# False
'c' in ['a', 'b', 'c']
# True
'a' not in [1, 2, 3]
# True
'c' not in ['a', 'b', 'c']
# False
Działa to również z krotkami, ponieważ krotki są haszowalne (w wyniku tego, że są również niezmienne):
(1, 2) in [(3, 4), (1, 2)]
# True
Jeśli obiekt w RHS definiuje __contains__()metodę, inwywoła ją wewnętrznie, jak zauważono w ostatnim akapicie rozdziału Porównania dokumentów.
... ini not insą obsługiwane przez typy, które są iterowalne lub implementują
__contains__()metodę. Na przykład możesz (ale nie powinieneś) to zrobić:
[3, 2, 1].__contains__(1)
# True
inzwiera, więc jeśli twój element znajduje się na początku listy, inocenia szybciej:
lst = list(range(10001))
%timeit 1 in lst
%timeit 10000 in lst # Expected to take longer time.
68.9 ns ± 0.613 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
178 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Jeśli chcesz zrobić coś więcej niż tylko sprawdzić, czy element znajduje się na liście, istnieją opcje:
list.indexmożna użyć do pobrania indeksu elementu. Jeśli ten element nie istnieje, powstaje a ValueError.
list.count można użyć, jeśli chcesz policzyć zdarzenia.
Problem XY: Czy rozważałeś sets?
Zadaj sobie następujące pytania:
- czy musisz sprawdzić, czy element jest na liście więcej niż jeden raz?
- Czy to sprawdzenie jest wykonywane wewnątrz pętli lub funkcji wywoływanej wielokrotnie?
- Czy elementy, które przechowujesz na liście, można przechować? IOW, możesz do
hashnich zadzwonić ?
Jeśli odpowiedziałeś „tak” na te pytania, powinieneś użyć setzamiast tego. inTest członków o lists O (n) Złożoność. Oznacza to, że python musi wykonać liniowy skan listy, odwiedzając każdy element i porównując go z wyszukiwanym elementem. Jeśli robisz to wielokrotnie lub jeśli listy są duże, ta operacja spowoduje narzut.
setobiekty, z drugiej strony, mieszają swoje wartości dla stałej kontroli członkostwa w czasie. Sprawdzanie odbywa się również przy użyciu in:
1 in {1, 2, 3}
# True
'a' not in {'a', 'b', 'c'}
# False
(1, 2) in {('a', 'c'), (1, 2)}
# True
Jeśli na tyle nieszczęście, że element, którego szukasz / nie szukasz, znajduje się na końcu listy, python przeskanuje listę do końca. Jest to widoczne z poniższych czasów:
l = list(range(100001))
s = set(l)
%timeit 100000 in l
%timeit 100000 in s
2.58 ms ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
101 ns ± 9.53 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Przypominamy, że jest to odpowiednia opcja, o ile elementy, które przechowujesz i przeglądasz, są haszowalne. IOW musiałyby to być niezmienne typy lub obiekty, które implementują __hash__.
3 -1 > 0 and (4-1 , 5) not in []⤇Truedlatego błąd nie jest priorytetem operatora.