recorrer - ejercicios resueltos de diccionarios en python
Renombrar una clave de diccionario (6)
¿Hay una manera de cambiar el nombre de una clave de diccionario, sin reasignar su valor a un nuevo nombre y eliminar la clave de nombre anterior; y sin iterar a través de dict key / value?
En el caso de OrderedDict, haga lo mismo, manteniendo la posición de esa clave.
Algunas personas antes de mí mencionaron el truco .pop
para eliminar y crear una clave en una sola línea.
Personalmente encuentro que la implementación más explícita es más legible:
d = {''a'': 1, ''b'': 2}
v = d[''b'']
del d[''b'']
d[''c''] = v
El código anterior devuelve {''a'': 1, ''c'': 2}
El mejor método en 1 línea:
>>> d = {''test'':[0,1,2]}
>>> d[''test2''] = d.pop(''test'')
>>> d
{''test2'': [0, 1, 2]}
Otras respuestas son bastante buenas. Pero en python3.6, el dict regular también tiene orden. Así que es difícil mantener la posición de la llave en un caso normal.
def rename(old_dict,old_name,new_name):
new_dict = {}
for key,value in zip(old_dict.keys(),old_dict.values()):
new_key = key if key != old_name else new_name
new_dict[new_key] = old_dict[key]
return new_dict
Para un dict regular, puedes usar:
mydict[new_key] = mydict.pop(old_key)
Para un OrderedDict, creo que debes construir uno completamente nuevo usando una comprensión.
>>> OrderedDict(zip(''123'', ''abc''))
OrderedDict([(''1'', ''a''), (''2'', ''b''), (''3'', ''c'')])
>>> oldkey, newkey = ''2'', ''potato''
>>> OrderedDict((newkey if k == oldkey else k, v) for k, v in _.viewitems())
OrderedDict([(''1'', ''a''), (''potato'', ''b''), (''3'', ''c'')])
La modificación de la clave en sí misma, como parece estar preguntando esta pregunta, no es práctica porque las claves dict son generalmente objetos inmutables como números, cadenas o tuplas. En lugar de intentar modificar la clave, reasignar el valor a una nueva clave y eliminar la clave anterior es cómo se puede lograr el "cambio de nombre" en python.
Puede usar esta OrderedDict recipe
escrita por Raymond Hettinger y modificarla para agregar un método de rename
, pero esto será una O (N) en complejidad:
def rename(self,key,new_key):
ind = self._keys.index(key) #get the index of old key, O(N) operation
self._keys[ind] = new_key #replace old key with new key in self._keys
self[new_key] = self[key] #add the new key, this is added at the end of self._keys
self._keys.pop(-1) #pop the last item in self._keys
Ejemplo:
dic = OrderedDict((("a",1),("b",2),("c",3)))
print dic
dic.rename("a","foo")
dic.rename("b","bar")
dic["d"] = 5
dic.rename("d","spam")
for k,v in dic.items():
print k,v
salida:
OrderedDict({''a'': 1, ''b'': 2, ''c'': 3})
foo 1
bar 2
c 3
spam 5
Usando un cheque para newkey!=oldkey
, de esta manera puede hacer:
if newkey!=oldkey:
dictionary[newkey] = dictionary[oldkey]
del dictionary[oldkey]