Moet ik ‘has_key()’ of ‘in’ gebruiken voor Python-dictaten?

Ik vraag me af wat ik beter kan doen:

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

of:

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

Antwoord 1, autoriteit 100%

inis zeker meer pythonisch.

In feite is has_key()verwijderd in Python 3.x.


Antwoord 2, autoriteit 18%

inwint zonder meer, niet alleen in elegantie (en niet verouderd;-) maar ook in prestaties, bijvoorbeeld:

$ 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

Hoewel de volgende observatie niet altijdwaar is, zul je merken dat meestalin Python de snellere oplossing eleganter en Pythonischer is; daarom is -mtimeitZO nuttig — het gaat er niet alleenom hier en daar honderd nanoseconden te besparen!-)


Antwoord 3, autoriteit 7%

Volgens python docs:

has_key()is verouderd ten gunste van
key in din.


Antwoord 4, autoriteit 3%

Gebruik dict.has_key()als (en alleen als) uw code moet kunnen worden uitgevoerd door Python-versies eerder dan 2.3 (toen key in dictwerd geïntroduceerd) .


Antwoord 5, autoriteit 2%

Er is één voorbeeld waarbij inje prestaties echt kapot maakt.

Als u ingebruikt op een O(1)-container die alleen __getitem__en has_key()implementeert, maar niet __contains__je verandert een O(1)-zoekopdracht in een O(N)-zoekopdracht (omdat interugvalt op een lineaire zoekopdracht via __getitem__).

Oplossen is duidelijk triviaal:

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

Antwoord 6

Uitbreiding van de prestatietests van Alex Martelli met de opmerkingen van Adam Parkin…

$ 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

Antwoord 7

Oplossing voor dict.has_key() is verouderd, gebruik ‘in’ — sublieme teksteditor 3

Hier heb ik een voorbeeld van een woordenboek met de naam ‘leeftijden’ genomen –

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"

Antwoord 8

has_keyis een woordenboekmethode, maar inwerkt op elke verzameling, en zelfs als __contains__ontbreekt, inzal elke andere methode gebruiken om de verzameling te herhalen om erachter te komen.


Antwoord 9

Als je zoiets als dit hebt:

t.has_key(ew)

wijzig het naar hieronder voor gebruik op Python 3.X en hoger:

key = ew
if key not in t

Other episodes