una ultimo metodos lista eliminar elementos elemento ejemplo diccionario dentro convertir como asociativo array agregar scripting dictionary python

scripting - ultimo - lista dentro de un diccionario python



¿Cómo eliminar elementos de un diccionario mientras se itera sobre él? (9)

Con python3, iterar en dic.keys () elevará el error de tamaño del diccionario. Puedes usar esta forma alternativa:

Probado con python3, funciona bien y el error "El diccionario cambió de tamaño durante la iteración " no se presenta:

my_dic = { 1:10, 2:20, 3:30 } # Is important here to cast because ".keys()" method returns a dict_keys object. key_list = list( my_dic.keys() ) # Iterate on the list: for k in key_list: print(key_list) print(my_dic) del( my_dic[k] ) print( my_dic ) # {}

Lo uso cuando, desde un diccionario que usa mucha memoria, quiero construir otro diccionario (que contenga la modificación del primero) sin hacer "copiar" y sobrecargar la RAM.

¿Es legítimo eliminar elementos de un diccionario en Python mientras se iteran sobre él?

Por ejemplo:

for k, v in mydict.iteritems(): if k == val: del mydict[k]

La idea es eliminar elementos del diccionario que no cumplan con una determinada condición, en lugar de crear un diccionario nuevo que sea un subconjunto del que se está repitiendo.

¿Es esta una buena solución? ¿Hay formas más elegantes / eficientes?


Es más limpio usar la list(mydict) :

>>> mydict = {''one'': 1, ''two'': 2, ''three'': 3, ''four'': 4} >>> for k in list(mydict): ... if k == ''three'': ... del mydict[k] ... >>> mydict {''four'': 4, ''two'': 2, ''one'': 1}

Esto corresponde a una estructura paralela para listas:

>>> mylist = [''one'', ''two'', ''three'', ''four''] >>> for k in list(mylist): # or mylist[:] ... if k == ''three'': ... mylist.remove(k) ... >>> mylist [''one'', ''two'', ''four'']

Ambos trabajan en python2 y python3.


Iterar sobre una copia en su lugar, como la devuelta por items() :

for k, v in list(mydict.items()):


No puedes modificar una colección mientras la estés iterando. De ese modo se encuentra la locura, sobre todo, si se le permitiera eliminar y eliminar el elemento actual, el iterador tendría que seguir adelante (+1) y la próxima llamada a la next lo llevaría más allá de eso (+2), por lo que '' d termina saltando un elemento (el que está justo detrás del que eliminó). Tienes dos opciones:

  • Copie todas las claves (o valores, o ambos, según lo que necesite), luego itere sobre ellos. Puede usar .keys() y otros para esto (en Python 3, pase el iterador resultante a la list ). Podría ser altamente desperdiciador de espacio sin embargo.
  • mydict sobre mydict como de costumbre, guardando las claves para eliminar en una colección separada to_delete . Cuando haya terminado de iterar mydict , elimine todos los elementos en to_delete de mydict . Ahorra algo de espacio (dependiendo de cuántas claves se eliminen y cuántas permanezcan) en el primer enfoque, pero también requiere algunas líneas más.

Primero puede crear una lista de claves para eliminar y luego iterar sobre esa lista para eliminarlas.

dict = {''one'' : 1, ''two'' : 2, ''three'' : 3, ''four'' : 4} delete = [] for k,v in dict.items(): if v%2 == 1: delete.append(k) for i in delete: del dict[i]


Probé las soluciones anteriores en Python3, pero esta parece ser la única que funciona para mí al almacenar objetos en un dict. Básicamente, usted hace una copia de su dict () y la itera mientras elimina las entradas en su diccionario original.

tmpDict = realDict.copy() for key, value in tmpDict.items(): if value: del(realDict[key])


Puede utilizar un diccionario de comprensión.

d = {k:d[k] for k in d if d[k] != val}


También puedes hacerlo en dos pasos:

remove = [k for k in mydict if k == val] for k in remove: del mydict[k]

Mi enfoque favorito suele ser simplemente hacer un nuevo dictado:

# Python 2.7 and 3.x mydict = { k:v for k,v in mydict.items() if k!=val } # before Python 2.7 mydict = dict((k,v) for k,v in mydict.iteritems() if k!=val)


Una prueba simple en la consola muestra que no puede modificar un diccionario mientras se itera sobre él:

>>> mydict = {''one'': 1, ''two'': 2, ''three'': 3, ''four'': 4} >>> for k, v in mydict.iteritems(): ... if k == ''two'': ... del mydict[k] ... ------------------------------------------------------------ Traceback (most recent call last): File "<ipython console>", line 1, in <module> RuntimeError: dictionary changed size during iteration

Como se indica en la respuesta de Delnan, eliminar entradas causa problemas cuando el iterador intenta pasar a la siguiente entrada. En su lugar, use el método keys() para obtener una lista de las claves y trabajar con eso:

>>> for k in mydict.keys(): ... if k == ''two'': ... del mydict[k] ... >>> mydict {''four'': 4, ''three'': 3, ''one'': 1}

Si necesita eliminar según el valor de los elementos, use el método items() lugar:

>>> for k, v in mydict.items(): ... if v == 3: ... del mydict[k] ... >>> mydict {''four'': 4, ''one'': 1}

EDITAR:

Lo anterior no funcionará para Python3 y dará un RuntimeError .

RuntimeError: el tamaño del diccionario cambió durante la iteración.

Esto sucede porque mydict.keys() devuelve un iterador, no una lista. Como se señaló en los comentarios, simplemente convierta mydict.keys() en una lista por list(mydict.keys()) y debería funcionar.