Mam listę krotek w Pythonie i mam warunek, w którym chcę wziąć gałąź TYLKO, jeśli krotki nie ma na liście (jeśli jest na liście, to nie chcę brać gałęzi if)
if curr_x -1 > 0 and (curr_x-1 , curr_y) not in myList:
# Do Something
Jednak tak naprawdę to dla mnie nie działa. Co zrobiłem źle?
3 -1 > 0 and (4-1 , 5) not in []
⤇True
dlatego błąd nie jest priorytetem operatora.myList.count((curr_x, curr_y))
, jeśli go(curr_x, curr_y)
nie mamyList
, wynik będzie0
Odpowiedzi:
Błąd jest prawdopodobnie gdzie indziej w twoim kodzie, ponieważ powinien działać dobrze:
Lub z krotkami:
źródło
if not ELEMENT in COLLECTION:
A not in B
sprowadza się do robienianot B.__contains__(A)
tego, conot A in B
jest zredukowane do tego, co jestnot B.__contains__(A)
.__notcontains__
. Przepraszam, to co powiedziałem, to bzdury.not
mieć wyższy priorytet niż ten,in
który nie ma. Zastanów się,ast.dump(ast.parse("not A in B").body[0])
którego rezultatem w"Expr(value=UnaryOp(op=Not(), operand=Compare(left=Name(id='A', ctx=Load()), ops=[In()], comparators=[Name(id='B', ctx=Load())])))"
przypadkunot
ścisłego pogrupowania do A można się spodziewać, że wynik będzie"Expr(value=Compare(left=UnaryOp(op=Not(), operand=Name(id='A', ctx=Load())), ops=[In()], comparators=[Name(id='B', ctx=Load())]))"
analizowany"(not A) in B"
.Najtańszym i najbardziej czytelnym rozwiązaniem jest użycie
in
operatora (lub w konkretnym przypadkunot in
). Jak wspomniano w dokumentacji,Dodatkowo,
y not in x
jest logicznie taki sam jaknot y in x
.Oto kilka przykładów:
Działa to również z krotkami, ponieważ krotki są haszowalne (w wyniku tego, że są również niezmienne):
Jeśli obiekt w RHS definiuje
__contains__()
metodę,in
wywoła ją wewnętrznie, jak zauważono w ostatnim akapicie rozdziału Porównania dokumentów.in
zwiera, więc jeśli twój element znajduje się na początku listy,in
ocenia szybciej:Jeśli chcesz zrobić coś więcej niż tylko sprawdzić, czy element znajduje się na liście, istnieją opcje:
list.index
można użyć do pobrania indeksu elementu. Jeśli ten element nie istnieje, powstaje aValueError
.list.count
można użyć, jeśli chcesz policzyć zdarzenia.Problem XY: Czy rozważałeś
set
s?Zadaj sobie następujące pytania:
hash
nich zadzwonić ?Jeśli odpowiedziałeś „tak” na te pytania, powinieneś użyć
set
zamiast tego.in
Test członków olist
s 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.set
obiekty, z drugiej strony, mieszają swoje wartości dla stałej kontroli członkostwa w czasie. Sprawdzanie odbywa się również przy użyciuin
: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:
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__
.źródło