Controlla se una determinata chiave esiste già in un dizionario e incrementala
-
19-08-2019 - |
Domanda
Dato un dizionario, come posso sapere se una determinata chiave in quel dizionario è già stata impostata su un valore diverso da Nessuno?
Cioè, voglio fare questo:
my_dict = {}
if (my_dict[key] != None):
my_dict[key] = 1
else:
my_dict[key] += 1
Ad esempio, voglio incrementare il valore se ce n'è già uno lì, o impostarlo su 1 altrimenti.
Soluzione
Stai cercando collections.defaultdict
(disponibile per Python 2.5+). Questo
from collections import defaultdict
my_dict = defaultdict(int)
my_dict[key] += 1
farà quello che vuoi.
Per i normali dict
di Python, se non esiste un valore per una determinata chiave, non riceverai None
quando accedi al dict - - verrà generato un KeyError
. Quindi se vuoi usare un dict
normale, invece del tuo codice dovresti usare
if key in my_dict:
my_dict[key] += 1
else:
my_dict[key] = 1
Altri suggerimenti
Preferisco farlo in una riga di codice.
my_dict = {} my_dict[some_key] = my_dict.get(some_key, 0) + 1
I dizionari hanno una funzione, get, che accetta due parametri: la chiave desiderata e un valore predefinito se non esiste. Preferisco questo metodo a defaultdict poiché vuoi solo gestire il caso in cui la chiave non esiste in questa riga di codice, non ovunque.
Personalmente mi piace usare setdefault()
my_dict = {}
my_dict.setdefault(some_key, 0)
my_dict[some_key] += 1
Per questo hai bisogno della chiave in dict
.
if key in my_dict and not (my_dict[key] is None):
# do something
else:
# do something else
Tuttavia, dovresti probabilmente considerare l'utilizzo di defaultdict
(come suggerito dF).
Per rispondere alla domanda " come posso sapere se un determinato indice in quel dict è già stato impostato su un valore non-None " ;, preferirei questo:
try:
nonNone = my_dict[key] is not None
except KeyError:
nonNone = False
Ciò è conforme al concetto già invocato di EAFP (più facile chiedere perdono che permesso). Evita anche la ricerca di chiavi duplicate nel dizionario come in in my_dict e my_dict [key] non è None
ciò che è interessante se la ricerca è costosa.
Per l'attuale problema che hai posto, cioè aumentando un int se esiste o impostandolo su un valore predefinito in caso contrario, ti consiglio anche
my_dict[key] = my_dict.get(key, default) + 1
come nella risposta di Andrew Wilkinson.
Esiste una terza soluzione se si memorizzano oggetti modificabili nel dizionario. Un esempio comune di ciò è una multimap , in cui è memorizzato un elenco di elementi per le chiavi. In tal caso, puoi utilizzare:
my_dict.setdefault(key, []).append(item)
Se nel dizionario non esiste un valore per chiave, il metodo setdefault lo imposterà sul secondo parametro di setdefault. Si comporta come un my_dict standard [chiave], restituendo il valore per la chiave (che potrebbe essere il valore appena impostato).
Concordato con cgoldberg. Come lo faccio è:
try:
dict[key] += 1
except KeyError:
dict[key] = 1
Quindi, o fai come sopra, oppure usa un dict predefinito come altri hanno suggerito. Non usare if dichiarazioni. Questo non è Pythonic.
Come puoi vedere dalle molte risposte, ci sono diverse soluzioni. Un'istanza di LBYL (prima di saltare) non è stata ancora menzionata, il metodo has_key ():
my_dict = {}
def add (key):
if my_dict.has_key(key):
my_dict[key] += 1
else:
my_dict[key] = 1
if __name__ == '__main__':
add("foo")
add("bar")
add("foo")
print my_dict
Il modo in cui stai cercando di farlo si chiama LBYL (guarda prima di saltare), poiché stai verificando le condizioni prima di provare ad aumentare il tuo valore.
L'altro approccio si chiama EAFP (è più facile chiedere perdono che permesso). In tal caso, dovresti semplicemente provare l'operazione (incrementare il valore). Se fallisce, prendi l'eccezione e imposti il ??valore su 1. Questo è un modo leggermente più Pythonic per farlo (IMO).
http://mail.python.org/pipermail /python-list/2003-May/205182.html
Un po 'in ritardo, ma dovrebbe funzionare.
my_dict = {}
my_dict[key] = my_dict[key] + 1 if key in my_dict else 1
Questo non risponde direttamente alla domanda, ma a me sembra che tu voglia la funzionalità di collections.Counter .
from collections import Counter
to_count = ["foo", "foo", "bar", "baz", "foo", "bar"]
count = Counter(to_count)
print(count)
print("acts just like the desired dictionary:")
print("bar occurs {} times".format(count["bar"]))
print("any item that does not occur in the list is set to 0:")
print("dog occurs {} times".format(count["dog"]))
print("can iterate over items from most frequent to least:")
for item, times in count.most_common():
print("{} occurs {} times".format(item, times))
Ciò comporta l'output
Counter({'foo': 3, 'bar': 2, 'baz': 1})
acts just like the desired dictionary:
bar occurs 2 times
any item that does not occur in the list is set to 0:
dog occurs 0 times
can iterate over items from most frequent to least:
foo occurs 3 times
bar occurs 2 times
baz occurs 1 times
Ecco una riga che mi è venuta di recente per risolvere questo problema. È basato sul setdefault metodo del dizionario:
my_dict = {}
my_dict[key] = my_dict.setdefault(key, 0) + 1
Lo stavo cercando, non l'ho trovato sul web, poi ho tentato la fortuna con Try / Error e l'ho trovato
my_dict = {}
if my_dict.__contains__(some_key):
my_dict[some_key] += 1
else:
my_dict[some_key] = 1