tutorial - python wiki




'has_key()' oder 'in'? (8)

Alex Martellis Leistungstests mit Adam Parkins Kommentaren erweitert ...

$ 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

Ich frage mich, was ist besser zu tun:

d = {'a': 1, 'b': 2}
'a' in d
True

oder:

d = {'a': 1, 'b': 2}
d.has_key('a')
True

Die API sieht aus einem bestimmten Grund so aus ... Mit den eingebauten Typ APIs wie dokumentiert ist Pythonic ...

my_dict.get('key', default_value) sollten Sie my_dict.get('key', default_value) statt my_dict.get('key') or default_value .

Die Ausnahme wäre der Sonderfall, der alle falsch-äquivalenten Werte ( 0 , '' , [] usw.) my_dict von my_dict mit default_value .

Wenn Sie eigentlich einen Standardwert von einem Diktat erhalten möchten, verwenden Sie stattdessen collections.defaultdict anstelle des eingebauten dict ?

>>> from collections import defaultdict
>>> d42 = defaultdict(lambda: 42)
>>> d42['x'] = 18
>>> d42['x']
18
>>> d42['y']
42

Der gebräuchlichste Anwendungsfall für defaultdicts ist wahrscheinlich der Listentyp, zB:

>>> dl = defaultdict(list)
>>> for x, y in some_list_of_tuples:
...     dl[x].append(y)
>>>

Lösung für dict.has_key () ist veraltet, benutze 'in' - sublime text editor 3

Hier habe ich ein Beispiel für ein Wörterbuch namens 'alters' 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"

Laut Python- docs :

has_key() ist veraltet zugunsten von key in d .


Verwenden Sie dict.has_key() wenn (und nur wenn) Ihr Code in Python-Versionen vor 2.3 dict.has_key() wenn key in dict wurde).


Wenn Sie einen Standardwert für den Fall verwenden möchten, dass sich ein Schlüssel nicht im Wörterbuch befindet, dann

my_dict.get('key') or default_value

ist eine Möglichkeit, die Kontrolle zu überspringen. get returns None wenn der Schlüssel nicht im Wörterbuch ist. Die Geschwindigkeit ist auch O (1) wie bei der Verwendung in .

Sie können auch verwenden

my_dict.get('key', default_value)

aber ich finde das weniger lesbar.


gewinnt in der Hand, nicht nur in der Eleganz (und nicht veraltet ;-) sondern auch in der 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

Während die folgende Beobachtung nicht immer wahr ist, werden Sie bemerken, dass in Python die schnellere Lösung normalerweise eleganter und Pythonic ist; deshalb ist -mtimeit so hilfreich - es geht nicht nur darum, hier und da hundert Nanosekunden zu speichern! -)


has_key ist eine Dictionary-Methode, in jedoch jede Collection __contains__ wird, und selbst wenn __contains__ fehlt, verwendet in jeder anderen Methode die Collection, um dies herauszufinden.







python