Compruebe si ya existe una clave determinada en un diccionario e increméntela

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

  •  19-08-2019
  •  | 
  •  

Pregunta

Dado un diccionario, ¿cómo puedo saber si una clave dada en ese diccionario ya se ha establecido en un valor distinto de Ninguno?

Es decir, quiero hacer esto:

my_dict = {}

if (my_dict[key] != None):
  my_dict[key] = 1
else:
  my_dict[key] += 1

Es decir, quiero incrementar el valor si ya hay uno allí, o establecerlo en 1 de lo contrario.

¿Fue útil?

Solución

Está buscando collections.defaultdict (disponible para Python 2.5+). Esto

from collections import defaultdict

my_dict = defaultdict(int)
my_dict[key] += 1

hará lo que quieras.

Para Python dict s normal, si no hay ningún valor para una clave determinada, no obtendrá None cuando acceda al dict - - se generará un KeyError . Entonces, si desea usar un dict regular, en lugar de su código, usaría

if key in my_dict:
    my_dict[key] += 1
else:
    my_dict[key] = 1

Otros consejos

Prefiero hacer esto en una línea de código.

my_dict = {}

my_dict[some_key] = my_dict.get(some_key, 0) + 1

Los diccionarios tienen una función, get, que toma dos parámetros: la clave que desea y un valor predeterminado si no existe. Prefiero este método por defecto, ya que solo desea manejar el caso donde la clave no existe en esta línea de código, no en todas partes.

Personalmente me gusta usar setdefault()

my_dict = {}

my_dict.setdefault(some_key, 0)
my_dict[some_key] += 1

Necesitas la tecla en dict idioma para eso.

if key in my_dict and not (my_dict[key] is None):
  # do something
else:
  # do something else

Sin embargo, probablemente debería considerar usar defaultdict (como se sugiere dF).

Para responder a la pregunta " ¿cómo puedo saber si un índice dado en ese dict ya se ha establecido en un valor que no es Ninguno? " ;, preferiría esto:

try:
  nonNone = my_dict[key] is not None
except KeyError:
  nonNone = False

Esto se ajusta al concepto ya invocado de EAFP (es más fácil pedir perdón que permiso). También evita la búsqueda de claves duplicadas en el diccionario como lo haría en key en my_dict y my_dict [key] no es None lo que es interesante si la búsqueda es costosa.

Para el problema real que ha planteado, es decir, incrementar un int si existe o establecerlo en un valor predeterminado, de lo contrario, también recomiendo el

my_dict[key] = my_dict.get(key, default) + 1

como en la respuesta de Andrew Wilkinson.

Hay una tercera solución si está almacenando objetos modificables en su diccionario. Un ejemplo común de esto es un multimap , donde almacena una lista de elementos para sus claves. En ese caso, puede usar:

my_dict.setdefault(key, []).append(item)

Si no existe un valor para la clave en el diccionario, el método setdefault lo establecerá en el segundo parámetro de setdefault. Se comporta como un my_dict [clave] estándar, devolviendo el valor de la clave (que puede ser el nuevo valor establecido).

De acuerdo con cgoldberg. Cómo lo hago es:

try:
    dict[key] += 1
except KeyError:
    dict[key] = 1

Por lo tanto, hágalo como se indica arriba o use un dict predeterminado como otros han sugerido. No use declaraciones if. Eso no es Pythonic.

Como puede ver en las muchas respuestas, hay varias soluciones. Todavía no se ha mencionado una instancia de LBYL (mira antes de saltar), el método 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

La forma en que intenta hacerlo se llama LBYL (mire antes de saltar), ya que está verificando las condiciones antes de intentar aumentar su valor.

El otro enfoque se llama EAFP (es más fácil pedir perdón que permiso). En ese caso, simplemente intentaría la operación (incremente el valor). Si falla, detecta la excepción y establece el valor en 1. Esta es una forma un poco más pitónica de hacerlo (IMO).

http://mail.python.org/pipermail /python-list/2003-May/205182.html

Un poco tarde pero esto debería funcionar.

my_dict = {}
my_dict[key] = my_dict[key] + 1 if key in my_dict else 1

Esto no responde directamente a la pregunta, pero para mí, parece que puede querer la funcionalidad de 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))

Esto da como resultado la salida

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

Aquí hay una frase que se me ocurrió recientemente para resolver este problema. Se basa en el setdefault método de diccionario:

my_dict = {}
my_dict[key] = my_dict.setdefault(key, 0) + 1

Lo estaba buscando, no lo encontré en la web, luego probé suerte con Try / Error y lo encontré

my_dict = {}

if my_dict.__contains__(some_key):
  my_dict[some_key] += 1
else:
  my_dict[some_key] = 1
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top