Controlla se una determinata chiave esiste già in un dizionario e incrementala

StackOverflow https://stackoverflow.com/questions/473099

  •  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.

È stato utile?

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top