it-swarm.com.de

Überprüfen Sie, ob sich etwas in einer Liste in Python befindet (nicht).

Ich habe eine Liste von Tupeln in Python , und ich habe eine Bedingung, wo ich den Zweig NUR nehmen möchte, wenn der Tupel nicht in der Liste ist (wenn er in der Liste ist, dann nicht) will den if Zweig nehmen)

if curr_x -1 > 0 and (curr_x-1 , curr_y) not in myList: 

    # Do Something

Das funktioniert bei mir allerdings nicht wirklich. Was habe ich falsch gemacht?

253
Zack

Der Fehler befindet sich wahrscheinlich an einer anderen Stelle in Ihrem Code, da er problemlos funktionieren sollte:

>>> 3 not in [2, 3, 4]
False
>>> 3 not in [4, 5, 6]
True

Oder mit Tupeln:

>>> (2, 3) not in [(2, 3), (5, 6), (9, 1)]
False
>>> (2, 3) not in [(2, 7), (7, 3), "hi"]
True
405
orlp

Wie überprüfe ich, ob sich etwas in einer Liste in Python befindet (nicht)?

Die billigste und am besten lesbare Lösung ist die Verwendung des Operators in (oder in Ihrem speziellen Fall not in). Wie in der Dokumentation erwähnt,

Die Operatoren in und not in testen auf Mitgliedschaft. x in s ergibt True, wenn x Mitglied von s ist, andernfalls False. x not in s gibt die Negation von x in s zurück.

Zusätzlich,

Der Operator not in hat den umgekehrten wahren Wert von in.

y not in x ist logisch dasselbe wie not y in x.

Hier einige Beispiele:

'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

Dies funktioniert auch mit Tupeln, da Tupel hashbar sind (aufgrund der Tatsache, dass sie auch unveränderlich sind):

(1, 2) in [(3, 4), (1, 2)]
#  True

Wenn das Objekt in der RHS eine __contains__() -Methode definiert, wird sie von in intern aufgerufen, wie im letzten Absatz des Abschnitts Comparisons der Dokumentation angegeben.

... in und not in werden von Typen unterstützt, die iterierbar sind oder die Methode __contains__() implementieren. Zum Beispiel könnten (sollten) Sie dies tun:

[3, 2, 1].__contains__(1)
# True

in schließt kurz. Wenn sich Ihr Element also am Anfang der Liste befindet, wird in schneller ausgewertet:

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)

Wenn Sie mehr als nur prüfen möchten, ob sich ein Element in einer Liste befindet, haben Sie folgende Möglichkeiten:

  • list.index kann verwendet werden, um den Index eines Elements abzurufen. Wenn dieses Element nicht vorhanden ist, wird ein ValueError ausgelöst.
  • list.count kann verwendet werden, wenn Sie die Vorkommen zählen möchten.

Das XY-Problem: Haben Sie sets in Betracht gezogen?

Stellen Sie sich folgende Fragen:

  • müssen Sie überprüfen, ob ein Element mehr als einmal in einer Liste enthalten ist?
  • Wird diese Prüfung innerhalb einer Schleife oder einer wiederholt aufgerufenen Funktion durchgeführt?
  • Sind die Artikel, die Sie auf Ihrer Liste speichern, hashbar? IOW, kannst du hash anrufen?

Wenn Sie diese Fragen mit "Ja" beantwortet haben, sollten Sie stattdessen set verwenden. Ein in-Mitgliedschaftstest für lists ist O(n) zeitlich komplex. Dies bedeutet, dass python einen linearen Scan Ihrer Liste durchführen muss, wobei jedes Element besucht und mit dem Suchbegriff verglichen wird. Wenn Sie dies wiederholt ausführen oder wenn die Listen groß sind, verursacht dieser Vorgang einen Mehraufwand.

set-Objekte hingegen haben ihre Werte für die ständige Überprüfung der Zeitzugehörigkeit. Die Prüfung erfolgt auch mit in:

1 in {1, 2, 3} 
# True

'a' not in {'a', 'b', 'c'}
# False

(1, 2) in {('a', 'c'), (1, 2)}
# True

Wenn Sie das Pech haben, dass sich das Element, nach dem Sie suchen/das Sie nicht suchen, am Ende Ihrer Liste befindet, hat python die Liste bis zum Ende durchsucht. Dies geht aus den folgenden Zeitpunkten hervor:

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)

Zur Erinnerung, dies ist eine geeignete Option, solange die Elemente, die Sie speichern und nachschlagen, hashbar sind. IOW, es müssten entweder unveränderliche Typen oder Objekte sein, die __hash__ implementieren.

9
cs95