valor recorrer elementos ejemplo diccionarios diccionario dentro buscar agregar python python-3.x dictionary

python - recorrer - Cómo copiar un diccionario y solo editar la copia.



diccionarios en python (17)

Cada variable en python (cosas como dict1 o str o __builtins__ es un puntero a algún "objeto" platónico oculto dentro de la máquina.

Si establece dict1 = dict2 , simplemente apunte dict1 al mismo objeto (o ubicación de memoria, o cualquier analogía que desee) como dict2 . Ahora, el objeto al que hace referencia dict1 es el mismo objeto al que hace referencia dict2 .

Puede comprobar: dict1 is dict2 debe ser True . Además, id(dict1) debería ser el mismo que id(dict2) .

Desea dict1 = copy(dict2) , o dict1 = deepcopy(dict2) .

¿La diferencia entre copy y copy deepcopy ? deepcopy se asegurará de que los elementos de dict2 (¿lo dict2 a una lista?) también sean copias.

No deepcopy mucho el deepcopy , por lo general es una mala práctica escribir código que lo necesite (en mi opinión).

¿Puede alguien explicarme esto por favor? Esto no tiene ningún sentido para mí.

Copio un diccionario en otro y edito el segundo y ambos se cambian. ¿Por qué está pasando esto?

>>> dict1 = {"key1": "value1", "key2": "value2"} >>> dict2 = dict1 >>> dict2 {''key2'': ''value2'', ''key1'': ''value1''} >>> dict2["key2"] = "WHY?!" >>> dict1 {''key2'': ''WHY?!'', ''key1'': ''value1''}


Como han explicado otros, el dict incorporado no hace lo que quieres. Pero en Python2 (y probablemente 3 también) puede crear fácilmente una clase ValueDict que se copia con = para que pueda estar seguro de que el original no cambiará.

class ValueDict(dict): def __ilshift__(self, args): result = ValueDict(self) if isinstance(args, dict): dict.update(result, args) else: dict.__setitem__(result, *args) return result # Pythonic LVALUE modification def __irshift__(self, args): result = ValueDict(self) dict.__delitem__(result, args) return result # Pythonic LVALUE modification def __setitem__(self, k, v): raise AttributeError, / "Use /"value_dict<<=''%s'', .../" instead of /"d[%s] = .../"" % (k,k) def __delitem__(self, k): raise AttributeError, / "Use /"value_dict>>=''%s''/" instead of /"del d[%s]" % (k,k) def update(self, d2): raise AttributeError, / "Use /"value_dict<<=dict2/" instead of /"value_dict.update(dict2)/"" # test d = ValueDict() d <<=''apples'', 5 d <<=''pears'', 8 print "d =", d e = d e <<=''bananas'', 1 print "e =", e print "d =", d d >>=''pears'' print "d =", d d <<={''blueberries'': 2, ''watermelons'': 315} print "d =", d print "e =", e print "e[''bananas''] =", e[''bananas''] # result d = {''apples'': 5, ''pears'': 8} e = {''apples'': 5, ''pears'': 8, ''bananas'': 1} d = {''apples'': 5, ''pears'': 8} d = {''apples'': 5} d = {''watermelons'': 315, ''blueberries'': 2, ''apples'': 5} e = {''apples'': 5, ''pears'': 8, ''bananas'': 1} e[''bananas''] = 1 # e[0]=3 # would give: # AttributeError: Use "value_dict<<=''0'', ..." instead of "d[0] = ..."

Consulte el patrón de modificación de lvalor descrito aquí: Python 2.7 - limpie la sintaxis para la modificación de lvalue . La observación clave es que str e int comportan como valores en Python (aunque en realidad son objetos inmutables bajo el capó). Mientras observas eso, observa también que nada es mágicamente especial acerca de str o int . dict se puede usar de la misma manera, y puedo pensar en muchos casos en los que ValueDict tiene sentido.


Cuando asigna dict2 = dict1 , no está haciendo una copia de dict1 , lo que hace que dict2 sea ​​solo otro nombre para dict1 .

Para copiar los tipos mutables como diccionarios, use copy / deepcopy del módulo copy .

import copy dict2 = copy.deepcopy(dict1)


Debido a que Python funciona con referencia, entonces cuando hiciste dict2 = dict1 pasas una referencia a dict2, eso es lo mismo que dict1. Por lo tanto, cuando realiza un cambio en dict1 o dict2, cambia una referencia y ambos dictados. Lo siento si me equivoco algo en inglés.


En Python 3.5+ hay una forma más fácil de lograr una copia superficial utilizando el operador de desempaquetado **. Definido por Pep 448 .

>>>dict1 = {"key1": "value1", "key2": "value2"} >>>dict2 = {**dict1} >>>print(dict2) {''key1'': ''value1'', ''key2'': ''value2''} >>>dict2["key2"] = "WHY?!" >>>print(dict1) {''key1'': ''value1'', ''key2'': ''value2''} >>>print(dict2) {''key1'': ''value1'', ''key2'': ''WHY?!''}

** desempaqueta el diccionario en un diccionario nuevo que luego se asigna a dict2.

También podemos confirmar que cada diccionario tiene una identificación distinta.

>>>id(dict1) 178192816 >>>id(dict2) 178192600

Si se necesita una copia profunda, copy.deepcopy() sigue siendo el camino a seguir.


Esto me confundió también, inicialmente, porque venía de un fondo de C.

En C, una variable es una ubicación en la memoria con un tipo definido. La asignación a una variable copia los datos en la ubicación de memoria de la variable.

Pero en Python, las variables actúan más como punteros a objetos. Entonces, asignar una variable a otra no hace una copia, solo hace que el nombre de esa variable apunte al mismo objeto.


Las declaraciones de asignación en Python no copian objetos, crean enlaces entre un objetivo y un objeto.

entonces, dict2 = dict1 , resulta otro enlace entre dict2 y el objeto al que se refiere dict1 .

Si desea copiar un dict, puede utilizar el copy module . El módulo de copia tiene dos interfaces:

copy.copy(x) Return a shallow copy of x. copy.deepcopy(x) Return a deep copy of x.

La diferencia entre copia superficial y profunda solo es relevante para objetos compuestos (objetos que contienen otros objetos, como listas o instancias de clase):

Una copia superficial construye un nuevo objeto compuesto y luego (en la medida de lo posible) inserta referencias en él a los objetos que se encuentran en el original.

Una copia profunda construye un nuevo objeto compuesto y luego, recursivamente, inserta copias en él de los objetos encontrados en el original.

Por ejemplo, en Python 2.7.9:

>>> import copy >>> a = [1,2,3,4,[''a'', ''b'']] >>> b = a >>> c = copy.copy(a) >>> d = copy.deepcopy(a) >>> a.append(5) >>> a[4].append(''c'')

y el resultado es:

>>> a [1, 2, 3, 4, [''a'', ''b'', ''c''], 5] >>> b [1, 2, 3, 4, [''a'', ''b'', ''c''], 5] >>> c [1, 2, 3, 4, [''a'', ''b'', ''c'']] >>> d [1, 2, 3, 4, [''a'', ''b'']]


Las mejores y más fáciles formas de crear una copia de un dict tanto en Python 2.7 como en 3 son ...

Para crear una copia del diccionario simple (de un solo nivel):

1. Utilizando el método dict () , en lugar de generar una referencia que apunte al dict existente.

my_dict1 = dict() my_dict1["message"] = "Hello Python" print(my_dict1) # {''message'':''Hello Python''} my_dict2 = dict(my_dict1) print(my_dict2) # {''message'':''Hello Python''} # Made changes in my_dict1 my_dict1["name"] = "Emrit" print(my_dict1) # {''message'':''Hello Python'', ''name'' : ''Emrit''} print(my_dict2) # {''message'':''Hello Python''}

2. Usando el método de actualización incorporado () del diccionario de Python.

my_dict2 = dict() my_dict2.update(my_dict1) print(my_dict2) # {''message'':''Hello Python''} # Made changes in my_dict1 my_dict1["name"] = "Emrit" print(my_dict1) # {''message'':''Hello Python'', ''name'' : ''Emrit''} print(my_dict2) # {''message'':''Hello Python''}

Para crear una copia de diccionario anidado o complejo:

Utilice el módulo de copia incorporado, que proporciona operaciones de copia superficial y profunda genéricas. Este módulo está presente en Python 2.7 y 3. *

import copy my_dict2 = copy.deepcopy(my_dict1)


Puede copiar y editar la copia recién construida de una sola vez llamando al constructor dict con argumentos de palabras clave adicionales:

>>> dict1 = {"key1": "value1", "key2": "value2"} >>> dict2 = dict(dict1, key2="WHY?!") >>> dict1 {''key2'': ''value2'', ''key1'': ''value1''} >>> dict2 {''key2'': ''WHY?!'', ''key1'': ''value1''}


Puedes usar directamente:

dict2 = eval(repr(dict1))

donde objeto dict2 es una copia independiente de dict1, por lo que puede modificar dict2 sin afectar a dict1.

Esto funciona para cualquier tipo de objeto.


Python nunca copia implícitamente objetos. Cuando establece dict2 = dict1 , hace que se refieran al mismo objeto de dictado exacto, de modo que cuando lo mute, todas las referencias a él se refieren al objeto en su estado actual.

Si desea copiar el dict (lo cual es raro), debe hacerlo explícitamente con

dict2 = dict(dict1)

o

dict2 = dict1.copy()


También puede simplemente hacer un nuevo diccionario con una comprensión del diccionario. Esto evita la importación de copia.

dout = dict((k,v) for k,v in mydict.items())

Por supuesto en python> = 2.7 puedes hacer:

dout = {k:v for k,v in mydict.items()}

Pero para compatibilidades hacia atrás, el método superior es mejor.


porque, dict2 = dict1, dict2 contiene la referencia a dict1. Tanto dict1 como dict2 apuntan a la misma ubicación en la memoria. Este es solo un caso normal al trabajar con objetos mutables en Python. Cuando trabaje con objetos mutables en Python, debe tener cuidado ya que es difícil de depurar. Como el siguiente ejemplo.

my_users = { ''ids'':[1,2], ''blocked_ids'':[5,6,7] } ids = my_users.get(''ids'') ids.extend(my_users.get(''blocked_ids'')) #all_ids print ids#output:[1, 2, 5, 6, 7] print my_users #output:{''blocked_ids'': [5, 6, 7], ''ids'': [1, 2, 5, 6, 7]}

La intención de este ejemplo es obtener todas las ID de usuario, incluidas las ID bloqueadas. Que obtuvimos de la variable ids, pero también actualizamos el valor de my_users involuntariamente. cuando extendió los identificadores con blocked_ids my_users se actualizó porque los identificadores se refieren a my_users .


dict1 es un símbolo que hace referencia a un objeto de diccionario subyacente. Asignar dict1 a dict2 simplemente asigna la misma referencia. Cambiar el valor de una clave a través del símbolo dict2 cambia el objeto subyacente, que también afecta a dict1 . Esto es confuso.

Es mucho más fácil razonar acerca de valores inmutables que de referencias, así que haga copias siempre que sea posible:

person = {''name'': ''Mary'', ''age'': 25} one_year_later = {**person, ''age'': 26} # does not mutate person dict

Esto es sintácticamente lo mismo que:

one_year_later = dict(person, age=26)


dict2 = dict1 no copia el diccionario. Simplemente le da al programador una segunda forma ( dict2 ) para referirse al mismo diccionario.


>>> dict2 = dict1 # dict2 is bind to the same Dict object which binds to dict1, so if you modify dict2, you will modify the dict1

Hay muchas formas de copiar el objeto Dict, simplemente uso

dict_1 = { ''a'':1, ''b'':2 } dict_2 = {} dict_2.update(dict_1)


>>> x={''a'': 1, ''b'': {''m'': 4, ''n'': 5, ''o'': 6}, ''c'': 3} >>> u=x.copy() >>> v=dict(x) >>> import copy >>> w=copy.deepcopy(x) >>> x[''a'']=10 >>> x {''a'': 10, ''c'': 3, ''b'': {''m'': 4, ''o'': 6, ''n'': 5}} >>> u {''a'': 1, ''c'': 3, ''b'': {''m'': 4, ''o'': 6, ''n'': 5}} >>> v {''a'': 1, ''c'': 3, ''b'': {''m'': 4, ''o'': 6, ''n'': 5}} >>> w {''a'': 1, ''c'': 3, ''b'': {''m'': 4, ''o'': 6, ''n'': 5}} >>> x[''b''][''m'']=40 >>> x {''a'': 10, ''c'': 3, ''b'': {''m'': 40, ''o'': 6, ''n'': 5}} >>> u {''a'': 1, ''c'': 3, ''b'': {''m'': 40, ''o'': 6, ''n'': 5}} >>> v {''a'': 1, ''c'': 3, ''b'': {''m'': 40, ''o'': 6, ''n'': 5}} >>> w {''a'': 1, ''c'': 3, ''b'': {''m'': 4, ''o'': 6, ''n'': 5}}