Antworten:
in ist definitiv pythonischer.
In der Tat has_key()wurde in Python 3.x entfernt .
keys()nur eine satzartige Ansicht in ein Wörterbuch und keine Kopie x in d.keys(). Trotzdem x in dist mehr pythonisch.
x in d.keys(), dass ein temporäres Objekt erstellt und zerstört werden muss, einschließlich der damit verbundenen Speicherzuweisung, bei der x in d.keys()nur eine arithmetische Operation (Berechnung des Hash) und eine Suche durchgeführt werden. Beachten Sie, dass dies d.keys()nur etwa zehnmal so lang ist, was eigentlich immer noch nicht lange dauert. Ich habe nicht nachgesehen, bin mir aber ziemlich sicher, dass es nur O (1) ist.
in gewinnt zweifellos, nicht nur in Eleganz (und nicht veraltet zu sein ;-), sondern auch in Leistung, zB:
$ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d'
10000000 loops, best of 3: 0.0983 usec per loop
$ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)'
1000000 loops, best of 3: 0.21 usec per loop
Obwohl die folgende Beobachtung nicht immer zutrifft, werden Sie feststellen, dass in Python die schnellere Lösung normalerweise eleganter und pythonischer ist. Deshalb -mtimeitist es so hilfreich - es geht nicht nur darum, hier und da hundert Nanosekunden zu sparen! -)
has_keyscheint auch O (1) zu sein.
Laut Python- Dokumenten :
has_key()wird zugunsten von abgelehntkey in d.
has_key()wird jetzt in Python 3
Verwenden dict.has_key()Sie diese Option, wenn (und nur wenn) Ihr Code von Python-Versionen vor 2.3 (zum Zeitpunkt key in dictder Einführung) ausgeführt werden muss.
Es gibt ein Beispiel, bei dem inIhre Leistung tatsächlich beeinträchtigt wird.
Wenn Sie ineinen O (1) -Container verwenden, der nur implementiert __getitem__und has_key()nicht __contains__, wird eine O (1) -Suche in eine O (N) -Suche umgewandelt (da inauf eine lineare Suche über zurückgegriffen wird __getitem__).
Fix ist offensichtlich trivial:
def __contains__(self, x):
return self.has_key(x)
has_key()ist spezifisch für Python 2-Wörterbücher . in/ __contains__ist die richtige API; Für Container, in denen ein vollständiger Scan unvermeidbar ist, gibt es ohnehin keine has_key()Methode. Wenn es einen O (1) -Ansatz gibt, ist dieser anwendungsfallspezifisch, und der Entwickler muss den richtigen Datentyp für das Problem auswählen.
has_keyist eine Wörterbuch Methode, sondern inauf jeder Sammlung funktionieren wird, und selbst wenn __contains__, fehlt inwird eine andere Methode zu Iterierte die Sammlung verwenden , um herauszufinden.
inTests an rangeObjekten durchzuführen . Ich bin mir jedoch nicht so sicher, wie effizient Python 2 xrangeist. ;)
__contains__kann trivial berechnen, ob ein Wert im Bereich liegt oder nicht.
rangejedes Mal eine neue Instanz zu erstellen . Bei Verwendung einer einzelnen, bereits vorhandenen Instanz ist der Test "Ganzzahl im Bereich" in meinen Timings etwa 40% schneller.
Die Lösung für dict.has_key () ist veraltet. Verwenden Sie 'in' - den erhabenen Texteditor 3
Hier habe ich ein Beispiel für ein Wörterbuch mit dem Namen "Alter" genommen -
ages = {}
# Add a couple of names to the dictionary
ages['Sue'] = 23
ages['Peter'] = 19
ages['Andrew'] = 78
ages['Karren'] = 45
# use of 'in' in if condition instead of function_name.has_key(key-name).
if 'Sue' in ages:
print "Sue is in the dictionary. She is", ages['Sue'], "years old"
else:
print "Sue is not in the dictionary"
Erweiterung der Leistungstests von Alex Martelli mit Adam Parkins Kommentaren ...
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 301, in main
x = t.timeit(number)
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 178, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
d.has_key(12)
AttributeError: 'dict' object has no attribute 'has_key'
$ python2.7 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0872 usec per loop
$ python2.7 -mtimeit -s'd=dict.fromkeys(range(1999))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0858 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' '12 in d'
10000000 loops, best of 3: 0.031 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d'
10000000 loops, best of 3: 0.033 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' '12 in d.keys()'
10000000 loops, best of 3: 0.115 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d.keys()'
10000000 loops, best of 3: 0.117 usec per loop
Wenn Sie so etwas haben:
t.has_key(ew)
Ändern Sie es für die Ausführung unter Python 3.X und höher wie folgt:
key = ew
if key not in t
t.has_key(ew)Gibt zurück, Truewenn die Wertreferenzen ewauch ein Schlüssel im Wörterbuch sind. key not in tGibt zurück, Truewenn der Wert nicht im Wörterbuch enthalten ist. Darüber hinaus ist der key = ewAlias sehr, sehr redundant. Die richtige Schreibweise ist if ew in t. Welches ist, was die akzeptierte Antwort von 8 Jahren zuvor Ihnen bereits gesagt hat.