Tengo una lista de diccionarios en el siguiente formato:

list = [
{'name':'bob','age':12},
{'name':'jill','age':34}
]

Quiero eliminar el primer diccionario donde name es igual a un valor. ¿Hay una mejor manera de hacer esto?

value = 'bob'
for dict in list:
    if dict['name'] == value:
        list.remove(dict)
        break

Salida:

list = [
{'name':'jill','age':34}
]
0
lol 13 ene. 2017 a las 18:55

7 respuestas

La mejor respuesta
list1 = [
{'name':'bob','age':12},
{'name':'jill','age':34}
]

value = 'bob'

for i, item in enumerate(list1):
  if item['name'] == value:
    list1.pop(i)
    break
1
gipsy 13 ene. 2017 a las 16:07

Crearía una función de utilidad separada para hacerlo. Lo siguiente primero determina qué diccionarios (si los hay) cumplen los criterios, y luego pop s (elimina) el primero encontrado.

from operator import itemgetter

people = [
    {'name': 'bob', 'age': 12},
    {'name': 'jill', 'age': 34},
    {'name': 'bob', 'age': 14},
]

def remove(name, seq):
    """Remove first dictionary in seq with 'name' entry equal to name."""
    matches = [i for i,n in enumerate(map(itemgetter('name'), seq)) if n == name]
    if matches:
        seq.pop(matches[0])


remove('bob', people)
print(people)  # -> [{'name': 'jill', 'age': 34}, {'name': 'bob', 'age': 14}]
0
martineau 13 ene. 2017 a las 16:36

Si desea un revestimiento único, puede usar una expresión generadora con next(), que se cortocircuita una vez que haya encontrado el primer elemento para eliminar, y luego use list.remove():

l.remove(next(d for d in l if d['name'] == value))

Ejemplo:

>>> l = [{'name':'bob','age':12},{'name':'jill','age':34}]
>>> value = 'bob'
>>> l.remove(next(d for d in l if d['name'] == value))
>>> l
[{'name': 'jill', 'age': 34}]

Tenga en cuenta que esto generará un StopIteration si no se encuentra value, lo que se puede evitar, pero es un poco más largo porque aunque next() tiene un argumento predeterminado, list.remove() no :

>>> l = [{'name':'bob','age':12},{'name':'jill','age':34}]
>>> value = 'bob'
>>> value_to_remove = next((d for d in l if d['name'] == value), None)
>>> 'Value not in list' if value_to_remove is None else l.remove(value_to_remove)
>>> l
[{'name': 'jill', 'age': 34}]
>>> value_to_remove = next((d for d in l if d['name'] == value), None)
>>> 'Value not in list' if value_to_remove is None else l.remove(value_to_remove)
'Value not in list'
1
Chris_Rands 13 ene. 2017 a las 16:41

En mi opinión, usar filter es la forma más pitónica:

new_list = filter(lambda x: x['name'] != value, original_list)

Sin embargo, esto no se elimina de la lista original y crea una nueva en la memoria. La asignación de old_list = filter(...) imita la eliminación del original (al menos en el ámbito local), sin embargo, todavía queda la sobrecarga de memoria. Para listas pequeñas (y la mayoría de los casos) esto no jugará un papel importante. Si es así, lo siguiente podría ser más apropiado:

for item in original_list:
    if item['name'] == value:
        original_list.remove(item)
        break
0
a_guest 14 ene. 2017 a las 20:20

De la documentación de Python en los diccionarios.

https://docs.python.org/3/library/stdtypes.html#dict

D.clear () borrará todos los valores de un diccionario.

value = 'bob'
for dict in list:
    if dict['name'] == value:
        #Empty dictionary of all values, will now return {}
        dict.clear()
        break

Si el diccionario está en una lista de otros, simplemente puede sacarlo de la lista o eliminarlo de esta manera.

list2 = [x for x in list1 if x != {}]
0
Westly White 13 ene. 2017 a las 16:05

Este es un problema perfecto pandas. pandas es parte de la suite PyData (creo) y es ampliamente aceptado. Lo usaría para este tipo de problema fosho.

Python 3.5.2 |Anaconda custom (x86_64)| (default, Jul  2 2016, 17:52:12)
[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.28)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas as pd
>>> query_list = [ {'name':'bob','age':12}, {'name':'jill','age':34} ]
>>> DF = pd.DataFrame(query_list)
>>> DF
     age  name
0   12   bob
1   34  jill
>>> mask = DF["name"] != "bob"
>>> mask
0    False
1     True
Name: name, dtype: bool
>>> DF2 = DF.loc[mask,:]
>>> DF2
     age  name
1   34  jill
>>> DF2.to_dict()
{'age': {1: 34}, 'name': {1: 'jill'}}
1
O.rka 13 ene. 2017 a las 16:03
list1 = [
     {'name': 'bob', 'age':12},
     {'name': 'jill', 'age':34}
]

map(lambda d: d.pop('name', 0) if d['name'] == 'bob' else d, list1)
0
Moinuddin Quadri 13 ene. 2017 a las 23:05