1124 Stimmen

Soll ich 'has_key()' oder 'in' auf Python-Dicts verwenden?

Gegeben:

>>> d = {'a': 1, 'b': 2}

Welches der folgenden ist der beste Weg zu überprüfen, ob 'a' in d enthalten ist?

>>> 'a' in d
True

>>> d.has_key('a')
True

1620voto

tonfa Punkte 23380

in ist definitiv pythonischer.

Tatsächlich wurde has_key() in Python 3.x entfernt.

3 Stimmen

Als zusätzliche Information, in Python 3, um nach dem Vorhandensein in Werten anstelle von Schlüsseln zu überprüfen, versuche >>> 1 in d.values()

277 Stimmen

Ein kleiner Fallstrick, den es zu vermeiden gilt, ist sicherzustellen, dass Sie Folgendes tun: "Schlüssel in some_dict" anstelle von "Schlüssel in some_dict.keys()". Beide sind semantisch äquivalent, aber in Bezug auf die Leistung ist der letztere deutlich langsamer (O(n) gegenüber O(1)). Ich habe Leute gesehen, die "in dict.keys()" machen und denken, dass es expliziter und daher besser ist.

4 Stimmen

@AdamParkin Ich habe deinen Kommentar in meiner Antwort demonstriert stackoverflow.com/a/41390975/117471

274voto

Alex Martelli Punkte 805329

in gewinnt eindeutig, nicht nur an Eleganz (und nicht veraltet zu sein;-) sondern auch an Leistung, z. B.:

$ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d'
10000000 Schleifen, best of 3: 0.0983 usec pro Schleife
$ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)'
1000000 Schleifen, best of 3: 0.21 usec pro Schleife

Obwohl die folgende Beobachtung nicht immer zutrifft, werden Sie feststellen, dass in der Regel in Python die schnellere Lösung eleganter und Pythonic ist; deshalb ist -mtimeit SO hilfreich -- es geht nicht nur darum, hier und da hundert Nanosekunden zu sparen!:-)

4 Stimmen

Vielen Dank dafür, dass dies die Überprüfung erleichtert hat, dass "in some_dict" tatsächlich O(1) ist (versuchen Sie, die 99 zum Beispiel auf 1999 zu erhöhen, und Sie werden feststellen, dass die Laufzeit etwa gleich bleibt).

4 Stimmen

has_key scheint auch O(1) zu sein.

118voto

Nadia Alramli Punkte 105256

Laut Python docs:

has_key() ist veraltet zugunsten von key in d.

8 Stimmen

has_key() wurde in Python 3 entfernt

48voto

John Machin Punkte 78125

Verwenden Sie dict.has_key(), nur wenn Ihr Code lauffähig sein muss für Python-Versionen vor 2.3 (als key in dict eingeführt wurde).

5 Stimmen

Die WebSphere-Aktualisierung von 2013 verwendet Jython 2.1 als ihre Hauptsprache für Skripting. Daher ist dies leider immer noch eine nützliche Sache, die fünf Jahre nach Ihrer Notiz zu beachten ist.

0 Stimmen

Großartige Antwort! Um in Python-Versionen < 2.3 (in meinem Fall auch Jython 2.1) einen pythonischen Check zu erhalten, können Sie key in dict.keys() verwenden.

27voto

schlenk Punkte 6782

Es gibt ein Beispiel, wo in tatsächlich die Leistung beeinträchtigt.

Wenn Sie in auf einen O(1) Container verwenden, der nur __getitem__ und has_key() implementiert, aber nicht __contains__, verwandeln Sie eine O(1) Suche in eine O(N) Suche (da in auf eine lineare Suche über __getitem__ zurückgreift).

Die Lösung ist offensichtlich trivial:

def __contains__(self, x):
    return self.has_key(x)

9 Stimmen

Diese Antwort war zum Zeitpunkt der Veröffentlichung relevant, aber 99,95 % der Leser können sie sicher ignorieren. In den meisten Fällen, wenn Sie mit etwas so Obskur arbeiten, werden Sie es wissen.

4 Stimmen

Das ist wirklich kein Problem. has_key() ist spezifisch für Python 2 Dictionaries. in / __contains__ ist die richtige API zu verwenden; für Container, bei denen ein vollständiger Scan unvermeidbar ist, gibt es sowieso keine has_key()-Methode und wenn es einen O(1)-Ansatz gibt, dann ist dieser anwendungsspezifisch und es liegt am Entwickler, den richtigen Datentyp für das Problem auszuwählen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X