¿Verificar si el valor ya existe dentro de la lista de diccionarios en Python?

5 minutos de lectura

Avatar de usuario de AP257
AP257

Tengo una lista de Python de diccionarios de la siguiente manera:

a = [
    {'main_color': 'red', 'second_color':'blue'},
    {'main_color': 'yellow', 'second_color':'green'},
    {'main_color': 'yellow', 'second_color':'blue'},
]

Me gustaría verificar si ya existe un diccionario con una clave/valor en particular en la lista de la siguiente manera:

// is a dict with 'main_color'='red' in the list already?
// if not: add item

Avatar de usuario de Mark Byers
marca byers

Aquí hay una forma de hacerlo:

if not any(d['main_color'] == 'red' for d in a):
    # does not exist

La parte entre paréntesis es una expresión generadora que devuelve True para cada diccionario que tenga el par clave-valor que está buscando, de lo contrario False.


Si la clave también podría faltar, el código anterior puede darle una KeyError. Puedes arreglar esto usando get y proporcionando un valor predeterminado. Si no proporciona un por defecto valor, None es regresado.

if not any(d.get('main_color', default_value) == 'red' for d in a):
    # does not exist

  • Sorprendente sintaxis de una sola línea, ¡he buscado mucho esto! Tengo curiosidad de saber dónde en los documentos de Python que nos muestran podemos poner la operación de ‘for’ antes de ‘for’.

    – sylye

    11 de mayo de 2017 a las 11:26

  • Lo encontré, se llama Comprensiones de lista docs.python.org/2/whatsnew/2.0.html?highlight=comprehensions

    – sylye

    12 mayo 2017 a las 10:01

  • ¿Existe la posibilidad de probar si 'main_color': 'red' Y 'second_color':'blue' existir ?

    – Florencio

    7 mayo 2018 a las 23:19

  • ¿Hay alguna manera, una vez que la expresión se haya evaluado como verdadera o falsa, de realizar una acción en el valor sin tener que repetir el ciclo?

    – Bryce

    13 de junio de 2018 a las 15:06

  • no funciona cuando los datos vienen con “null” [{“main_color”:null,”second_color”:”red”}, {“main_color:”green”,”second_color”:”null”}]

    –Ashok Sri

    5 de septiembre de 2019 a las 12:53

Avatar de usuario de Tony Veijalainen
Tony Veijalainen

Tal vez esto ayude:

a = [{ 'main_color': 'red', 'second_color':'blue'},
     { 'main_color': 'yellow', 'second_color':'green'},
     { 'main_color': 'yellow', 'second_color':'blue'}]

def in_dictlist(key, value, my_dictlist):
    for entry in my_dictlist:
        if entry[key] == value:
            return entry
    return {}

print in_dictlist('main_color','red', a)
print in_dictlist('main_color','pink', a)

  • Actualización para la simplicidad. Sin embargo, a Py3 no le gustan los paréntesis extra

    – Dawoodjee

    15 de junio de 2021 a las 11:49


Avatar de usuario de Amitsas1
Amitsas1

Basado en la excelente respuesta de @Mark Byers y siguiendo la pregunta de @Florent, solo para indicar que también funcionará con 2 condiciones en la lista de dics con más de 2 claves:

names = []
names.append({'first': 'Nil', 'last': 'Elliot', 'suffix': 'III'})
names.append({'first': 'Max', 'last': 'Sam', 'suffix': 'IX'})
names.append({'first': 'Anthony', 'last': 'Mark', 'suffix': 'IX'})

if not any(d['first'] == 'Anthony' and d['last'] == 'Mark' for d in names):

    print('Not exists!')
else:
    print('Exists!')

Resultado:

Exists!

Quizás una función en este sentido es lo que buscas:

 def add_unique_to_dict_list(dict_list, key, value):
  for d in dict_list:
     if key in d:
        return d[key]

  dict_list.append({ key: value })
  return value

Solo otra forma de hacer lo que pidió el OP:

 if not filter(lambda d: d['main_color'] == 'red', a):
     print('Item does not exist')

filter filtraría la lista hasta el elemento que OP está probando. El if condition luego hace la pregunta, “Si este elemento no está allí”, entonces ejecute este bloque.

  • creo que esto tiene que ser if not list(filter(lambda d: d['main_color'] == 'red', a)): para crear un objeto de lista que luego prueba si está vacío o no. filter(..) como arriba crea un objeto de filtro que siempre será verdadero.

    – marca mcmurray

    25 oct 2021 a las 14:06

Avatar de usuario de René
René

Creo que sería un poco mejor verificar si la clave existe, ya que algunos comentaristas preguntaron debajo de la respuesta preferida, ingrese la descripción del enlace aquí.

Entonces, agregaría una pequeña cláusula if al final de la línea:


input_key = 'main_color'
input_value="red"

if not any(_dict[input_key] == input_value for _dict in a if input_key in _dict):
    print("not exist")

No estoy seguro, si es incorrecto, pero creo que el OP solicitó verificar si existe el par clave-valor y, de lo contrario, se debe agregar el par clave-valor.

En este caso, sugeriría una pequeña función:

a = [{ 'main_color': 'red', 'second_color': 'blue'},
     { 'main_color': 'yellow', 'second_color': 'green'},
     { 'main_color': 'yellow', 'second_color': 'blue'}]

b = None

c = [{'second_color': 'blue'},
     {'second_color': 'green'}]

c = [{'main_color': 'yellow', 'second_color': 'blue'},
     {},
     {'second_color': 'green'},
     {}]


def in_dictlist(_key: str, _value :str, _dict_list = None):
    if _dict_list is None:
        # Initialize a new empty list
        # Because Input is None
        # And set the key value pair
        _dict_list = [{_key: _value}]
        return _dict_list

    # Check for keys in list
    for entry in _dict_list:
        # check if key with value exists
        if _key in entry and entry[_key] == _value:
            # if the pair exits continue
            continue
        else:
            # if not exists add the pair
            entry[_key] = _value
    return _dict_list


_a = in_dictlist("main_color", "red", a )
print(f"{_a=}")
_b = in_dictlist("main_color", "red", b )
print(f"{_b=}")
_c = in_dictlist("main_color", "red", c )
print(f"{_c=}")

Producción:

_a=[{'main_color': 'red', 'second_color': 'blue'}, {'main_color': 'red', 'second_color': 'green'}, {'main_color': 'red', 'second_color': 'blue'}]
_b=[{'main_color': 'red'}]
_c=[{'main_color': 'red', 'second_color': 'blue'}, {'main_color': 'red'}, {'second_color': 'green', 'main_color': 'red'}, {'main_color': 'red'}]

  • creo que esto tiene que ser if not list(filter(lambda d: d['main_color'] == 'red', a)): para crear un objeto de lista que luego prueba si está vacío o no. filter(..) como arriba crea un objeto de filtro que siempre será verdadero.

    – marca mcmurray

    25 oct 2021 a las 14:06

avatar de usuario de samtoddler
samtoddler

Lo siguiente me funciona.

    #!/usr/bin/env python
    a = [{ 'main_color': 'red', 'second_color':'blue'},
    { 'main_color': 'yellow', 'second_color':'green'},
    { 'main_color': 'yellow', 'second_color':'blue'}]

    found_event = next(
            filter(
                lambda x: x['main_color'] == 'red',
                a
            ),
      #return this dict when not found
            dict(
                name="red",
                value="{}"
            )
        )

    if found_event:
        print(found_event)

    $python  /tmp/x
    {'main_color': 'red', 'second_color': 'blue'}

¿Ha sido útil esta solución?