Ik wilde testen of een sleutel in een woordenboek bestaat voordat ik de waarde voor de sleutel bijwerk.
Ik heb de volgende code geschreven:
if 'key1' in dict.keys():
print "blah"
else:
print "boo"
Ik denk dat dit niet de beste manier is om deze taak te volbrengen. Is er een betere manier om een sleutel in het woordenboek te testen?
Antwoord 1, autoriteit 100%
in
is de bedoelde manier om te testen op het bestaan van een sleutel in een dict
.
d = {"key1": 10, "key2": 23}
if "key1" in d:
print("this will execute")
if "nonexistent key" in d:
print("this will not")
Als u een standaardinstelling wilt, kunt u altijd dict.get()
:
d = dict()
for i in range(100):
key = i % 10
d[key] = d.get(key, 0) + 1
en als je altijd een standaardwaarde voor elke sleutel wilt hebben, kun je dict.setdefault()
herhaaldelijk of defaultdict
uit de collections
module, zoals zo:
from collections import defaultdict
d = defaultdict(int)
for i in range(100):
d[i % 10] += 1
maar over het algemeen is het sleutelwoord in
de beste manier om dit te doen.
Antwoord 2, autoriteit 38%
U hoeft geen toetsen te bellen:
if 'key1' in dict:
print("blah")
else:
print("boo")
Dat zal veel sneller zijn, omdat het de hashing van het woordenboek gebruikt in plaats van een lineaire zoekopdracht uit te voeren, wat het aanroepen van sleutels zou doen. doen.
Antwoord 3, autoriteit 7%
U kunt de aanwezigheid van een sleutel in een woordenboek testen met het trefwoord in:
d = {'a': 1, 'b': 2}
'a' in d # <== evaluates to True
'c' in d # <== evaluates to False
Een algemeen gebruik om de aanwezigheid van een sleutel in een woordenboek te controleren voordat deze wordt gemuteerd, is om de waarde standaard te initialiseren (bijvoorbeeld als uw waarden bijvoorbeeld lijsten zijn en u ervoor wilt zorgen dat er een lege lijst is waarnaar u kunt toevoegen bij het invoegen van de eerste waarde voor een sleutel). In dergelijke gevallen kunt u de collections.defaultdict()
type om interessant te zijn.
In oudere code vindt u mogelijk ook gebruik van has_key()
, een verouderde methode om de aanwezigheid van sleutels in woordenboeken te controleren (gebruik gewoon key_name in dict_name
, in plaats daarvan).
Antwoord 4, autoriteit 2%
U kunt uw code tot dit inkorten:
if 'key1' in my_dict:
...
Dit is echter op zijn best een cosmetische verbetering. Waarom denk je dat dit niet de beste manier is?
Antwoord 5, autoriteit 2%
Voor aanvullende informatie over snelheidsuitvoering van de voorgestelde methoden van het geaccepteerde antwoord (10 m lussen):
'key' in mydict
verstreken tijd 1,07 secmydict.get('key')
verstreken tijd 1,84 secmydefaultdict['key']
verstreken tijd 1,07 sec
Daarom wordt het gebruik van in
of defaultdict
aanbevolen tegen get
.
Antwoord 6
Ik raad aan om in plaats daarvan de setdefault
methode te gebruiken. Het klinkt alsof het alles zal doen wat je wilt.
>>> d = {'foo':'bar'}
>>> q = d.setdefault('foo','baz') #Do not override the existing key
>>> print q #The value takes what was originally in the dictionary
bar
>>> print d
{'foo': 'bar'}
>>> r = d.setdefault('baz',18) #baz was never in the dictionary
>>> print r #Now r has the value supplied above
18
>>> print d #The dictionary's been updated
{'foo': 'bar', 'baz': 18}
Antwoord 7
Woordenboek in python heeft een get(‘key’, default) methode. U kunt dus gewoon een standaardwaarde instellen voor het geval er geen sleutel is.
values = {...}
myValue = values.get('Key', None)
Antwoord 8
Hoe zit het met het gebruik van EAFP (gemakkelijker om vergeving te vragen dan toestemming):
try:
blah = dict["mykey"]
# key exists in dict
except KeyError:
# key doesn't exist in dict
Bekijk andere SO-berichten:
Try vs if in python gebruiken of
Controleren op het bestaan van leden in Python
Antwoord 9
De ternaire python-operator gebruiken:
message = "blah" if 'key1' in my_dict else "booh"
print(message)
Antwoord 10
De manieren waarop u de resultaten kunt krijgen zijn:
- if your_dict.has_key(key) Verwijderd in Python 3
- indien toets uw_dictaat
- probeer/behalve blokkeren
Wat beter is, hangt af van 3 dingen:
- Heeft het woordenboek ‘normaal gesproken de sleutel’ of ‘heeft normaal gesproken de sleutel niet’.
- Bent u van plan voorwaarden te gebruiken zoals if…else…elseif…else?
- Hoe groot is woordenboek?
Meer lezen: http://paltman.com/ probeer-behalve-performance-in-python-a-simple-test/
Gebruik van try/block in plaats van ‘in’ of ‘if’:
try:
my_dict_of_items[key_i_want_to_check]
except KeyError:
# Do the operation you wanted to do for "key not present in dict".
else:
# Do the operation you wanted to do with "key present in dict."
Antwoord 11
Alleen Python 2: (en Python 2.7 ondersteunt al `in`)
je kunt de has_key()
methode gebruiken:
if dict.has_key('xyz')==1:
#update the value for the key
else:
pass
Antwoord 12
Gewoon een FYI toevoeging aan Chris. B (beste antwoord):
d = defaultdict(int)
Werkt ook; de reden is dat het aanroepen van int()
0
retourneert, wat defaultdict
achter de schermen doet (bij het samenstellen van een woordenboek), vandaar de naam ” Fabrieksfunctie” in de documentatie.
Antwoord 13
Controleer of een bepaalde sleutel al in een woordenboek bestaat
Om een idee te krijgen hoe we dat moeten doen, bekijken we eerst welke methoden we op woordenboek kunnen gebruiken.
Dit zijn de methoden:
d={'clear':0, 'copy':1, 'fromkeys':2, 'get':3, 'items':4, 'keys':5, 'pop':6, 'popitem':7, 'setdefault':8, 'update':9, 'values':10}
Python Dictionary clear() Removes all Items
Python Dictionary copy() Returns Shallow Copy of a Dictionary
Python Dictionary fromkeys() Creates dictionary from given sequence
Python Dictionary get() Returns Value of The Key
Python Dictionary items() Returns view of dictionary (key, value) pair
Python Dictionary keys() Returns View Object of All Keys
Python Dictionary pop() Removes and returns element having given key
Python Dictionary popitem() Returns & Removes Element From Dictionary
Python Dictionary setdefault() Inserts Key With a Value if Key is not Present
Python Dictionary update() Updates the Dictionary
Python Dictionary values() Returns view of all values in dictionary
De brute methode om te controleren of de sleutel al bestaat, kan de get()
methode zijn:
d.get("key")
De andere twee interessante methoden items()
en keys()
klinken als teveel werk. Laten we dus eens kijken of get()
de juiste methode voor ons is. We hebben ons dictaat d
:
d= {'clear':0, 'copy':1, 'fromkeys':2, 'get':3, 'items':4, 'keys':5, 'pop':6, 'popitem':7, 'setdefault':8, 'update':9, 'values':10}
Afdrukken laat zien dat de sleutel die we niet hebben, None
teruggeeft:
print(d.get('key')) #None
print(d.get('clear')) #0
print(d.get('copy')) #1
We kunnen dat gebruiken om de info te krijgen of de sleutel aanwezig is of niet.
Maar overweeg dit als we een dictaat maken met een enkele key:None
:
d= {'key':None}
print(d.get('key')) #None
print(d.get('key2')) #None
Hierdoor is de get()
methode niet betrouwbaar in het geval dat sommige waarden None
zijn.
Dit verhaal zou een gelukkiger einde moeten hebben. Als we de in
-vergelijker gebruiken:
print('key' in d) #True
print('key2' in d) #False
We krijgen de juiste resultaten.
We kunnen de Python-bytecode onderzoeken:
import dis
dis.dis("'key' in d")
# 1 0 LOAD_CONST 0 ('key')
# 2 LOAD_NAME 0 (d)
# 4 COMPARE_OP 6 (in)
# 6 RETURN_VALUE
dis.dis("d.get('key2')")
# 1 0 LOAD_NAME 0 (d)
# 2 LOAD_METHOD 1 (get)
# 4 LOAD_CONST 0 ('key2')
# 6 CALL_METHOD 1
# 8 RETURN_VALUE
Dit toont aan dat de in
-operator voor vergelijken niet alleen betrouwbaarder is, maar zelfs sneller dan get()
.
Antwoord 14
Python-woordenboek heeft de methode __contains__
. Deze methode retourneert True als het woordenboek de sleutel heeft, anders retourneert False.
>>> temp = {}
>>> help(temp.__contains__)
Help on built-in function __contains__:
__contains__(key, /) method of builtins.dict instance
True if D has a key k, else False.
Antwoord 15
Een andere manier delen om te controleren of een sleutel bestaat met behulp van booleaanse operatoren.
d = {'a': 1, 'b':2}
keys = 'abcd'
for k in keys:
x = (k in d and 'blah') or 'boo'
print(x)
Dit geeft terug
>>> blah
>>> blah
>>> boo
>>> boo
Uitleg
Eerst moet je weten dat in Python, 0
, None
, of objecten met een lengte van nul de waarde False
opleveren. Al het andere wordt geëvalueerd als True
. Booleaanse bewerkingen worden van links naar rechts geëvalueerd en retourneren de operand niet True of False.
Laten we een voorbeeld bekijken:
>>> 'Some string' or 1/0
'Some string'
>>>
Sinds 'Some string'
wordt geëvalueerd tot True
, wordt de rest van de or
niet geëvalueerd en is er geen fout opgetreden bij deling door nul .
Maar als we de volgorde veranderen, wordt 1/0
eerst geëvalueerd en ontstaat er een uitzondering:
>>> 1/0 or 'Some string'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>>
We kunnen dit gebruiken voor patroon om te controleren of er een sleutel bestaat.
(k in d and 'blah')
doet hetzelfde als
if k in d:
'blah'
else:
False
Dit geeft al het juiste resultaat als de sleutel bestaat, maar we willen dat er ‘boo’ wordt afgedrukt als dat niet het geval is. Dus we nemen het resultaat en or
het met 'boo'
>>> False or 'boo'
'boo'
>>> 'blah' or 'boo'
'blah'
>>>
Antwoord 16
U kunt de for
-lus gebruiken om het woordenboek te herhalen en de naam van de sleutel te krijgen die u in het woordenboek wilt vinden, controleer daarna of deze bestaat of niet met behulp van if
staat:
dic = {'first' : 12, 'second' : 123}
for each in dic:
if each == 'second':
print('the key exists and the corresponding value can be updated in the dictionary')