python ciclo - Controlla se una determinata chiave esiste già in un dizionario




for (17)

Volevo testare se esiste una chiave in un dizionario prima di aggiornare il valore della chiave. Ho scritto il seguente codice:

if 'key1' in dict.keys():
  print "blah"
else:
  print "boo"

Penso che questo non sia il modo migliore per portare a termine questo compito. C'è un modo migliore per testare una chiave nel dizionario?


Answers

Il più semplice è se si sa quale chiave (nome della chiave) deve cercare:

# suppose your dictionary is
my_dict = {'foo': 1, 'bar': 2}
# check if a key is there
if 'key' in my_dict.keys():   # it will evaluates to true if that key is present otherwise false.
    # do something

oppure puoi anche fare semplicemente come:

if 'key' in my_dict:   # it will evaluates to true if that key is present otherwise false.
    # do something

print dict.get('key1', 'blah')

Non stamperà boo per i valori nel dict, ma raggiunge l'obiettivo stampando il valore di key1 per confermare invece la sua esistenza.


I modi in cui puoi ottenere i risultati sono:

  • se your_dict.has_key (chiave) Rimosso in Python 3
  • se digiti your_dict
  • prova / tranne il blocco

Quale è meglio dipende da 3 cose:

  1. Il dizionario "normalmente ha la chiave" o "normalmente non ha la chiave".
  2. Intendi usare condizioni come se ... else ... elseif ... else?
  3. Quanto è grande il dizionario?

Ulteriori informazioni: http://paltman.com/try-except-performance-in-python-a-simple-test/

Uso di try / block invece di "in" o "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."

Bene ... Sarai familiare che la ricerca dell'esistenza di un elemento in un elenco o di dati significa attraversare tutto (almeno per l'elenco non ordinato, ad es. Dict.keys). Invece di usare Eccezione ed errori che si presentano normalmente, possiamo evitare quella complessità ...

d={1:'a',2:'b'}
try:
    needed=d[3]
    print(needed)
except:
    print("Key doesnt exist")

in è il modo previsto per testare l'esistenza di una chiave in un dict .

d = dict()

for i in xrange(100):
    key = i % 10
    if key in d:
        d[key] += 1
    else:
        d[key] = 1

Se si desidera un valore predefinito, è sempre possibile utilizzare dict.get() :

d = dict()

for i in xrange(100):
    key = i % 10
    d[key] = d.get(key, 0) + 1

... e se si desidera garantire sempre un valore predefinito per qualsiasi chiave, è possibile utilizzare defaultdict dal modulo collections , in questo modo:

from collections import defaultdict

d = defaultdict(lambda: 0)

for i in xrange(100):
    d[i % 10] += 1

... ma in generale, la parola chiave in è il modo migliore per farlo.


Solo una FYI che aggiunge a Chris. B (risposta migliore):

d = defaultdict(int)

Funziona pure; il motivo è che la chiamata a int() restituisce 0 che è ciò che defaultdict fa dietro le quinte (quando costruisce un dizionario), da qui il nome "Factory Function" nella documentazione.


Per ulteriori informazioni sull'esecuzione rapida dei metodi proposti dalla risposta accettata (loop di 10 m):

  • 'key' in mydict tempo trascorso 1.07 sec
  • mydict.get('key') tempo trascorso 1.84 sec
  • mydefaultdict['key'] tempo trascorso 1.07 sec

Pertanto l'uso di in o defaultdict è raccomandato contro get .


Puoi abbreviare questo:

if 'key1' in dict:
    ...

Tuttavia, questo è nel migliore dei casi un miglioramento estetico. Perché credi che questo non sia il modo migliore?


Il dizionario in python ha un metodo get ('chiave', predefinito). Quindi puoi semplicemente impostare un valore predefinito nel caso in cui non ci sia una chiave.

values = {...}
myValue = values.get('Key', None)

Puoi usare il metodo has_key ():

if dict.has_key('xyz')==1:
    #update the value for the key
else:
    pass

Oppure il metodo dict.get per impostare un valore predefinito se non trovato:

mydict = {"a": 5}

print mydict["a"]            #prints 5
print mydict["b"]            #Throws KeyError: 'b'

print mydict.get("a", 0)     #prints 5
print mydict.get("b", 0)     #prints 0

È possibile verificare la presenza di una chiave in un dizionario, utilizzando la parola chiave in:

d = {'a': 1, 'b': 2}
'a' in d # <== evaluates to True
'c' in d # <== evaluates to False

Un uso comune per verificare l'esistenza di una chiave in un dizionario prima di mutarlo è quello di inizializzare il valore predefinito (ad es. Se i valori sono elenchi, ad esempio, e si vuole assicurarsi che ci sia una lista vuota alla quale si può aggiungere quando si inserisce il primo valore per una chiave). In casi come questi, è possibile che il tipo collections.defaultdict() sia di interesse.

Nel codice precedente, potresti anche trovare alcuni usi di has_key() , un metodo deprecato per verificare l'esistenza di chiavi nei dizionari (usa invece key_name in dict_name , invece).


Il dizionario Python ha il metodo chiamato __contains__ . Questo metodo restituirà True se il dizionario ha la chiave else restituisce 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.

Suggerirei invece di utilizzare il metodo setdefault . Sembra che farà tutto quello che vuoi.

>>> 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}

Per il controllo è possibile utilizzare il metodo has_key()

if dict.has_key('key1'):
   print "it is there"

Se si desidera un valore, è possibile utilizzare il metodo get()

a = dict.get('key1', expeced_type)

Se si desidera una tupla o un elenco o un dizionario o qualsiasi stringa come valore predefinito come valore di ritorno, utilizzare il metodo get()

a = dict.get('key1', {}).get('key2', [])

Utilizzando l'operatore ternario:

message = "blah" if 'key1' in dict else "booh"
print(message)

Non devi chiamare le chiavi:

if 'key1' in dict:
  print "blah"
else:
  print "boo"

Questo sarà molto faster in quanto utilizza l'hashing del dizionario invece di fare una ricerca lineare, che farebbe le chiavi di chiamata.


Una variante della risposta di FMc e user7177 fornirà un comando che può restituire tutti gli indici per qualsiasi voce:

>>> a = ['foo','bar','baz','bar','any', 'foo', 'much']
>>> l = dict(zip(set(a), map(lambda y: [i for i,z in enumerate(a) if z is y ], set(a))))
>>> l['foo']
[0, 5]
>>> l ['much']
[6]
>>> l
{'baz': [2], 'foo': [0, 5], 'bar': [1, 3], 'any': [4], 'much': [6]}
>>> 

Puoi anche usarlo come un unico liner per ottenere tutti gli indici per una singola voce. Non ci sono garanzie di efficienza, anche se ho usato il set (a) per ridurre il numero di volte in cui viene chiamata la lambda.







python dictionary