Tengo dos diccionarios Python, y quiero escribir una sola expresión que devuelva estos dos diccionarios, combinados. El método update()
sería lo que necesito, si devuelve su resultado en lugar de modificar un diccionario en el lugar.
>>> x = {'a': 1, 'b': 2}
>>> y = {'b': 10, 'c': 11}
>>> z = x.update(y)
>>> print(z)
None
>>> x
{'a': 1, 'b': 10, 'c': 11}
¿Cómo puedo obtener ese diccionario combinado final en z
, no en x
?
(Para ser más claro, el manejo del conflicto de último ganador de dict.update()
es lo que también estoy buscando).
30 respuestas
Si crees que las lambdas son malvadas, no sigas leyendo. Según lo solicitado, puede escribir la solución rápida y eficiente en la memoria con una expresión:
x = {'a':1, 'b':2}
y = {'b':10, 'c':11}
z = (lambda a, b: (lambda a_copy: a_copy.update(b) or a_copy)(a.copy()))(x, y)
print z
{'a': 1, 'c': 11, 'b': 10}
print x
{'a': 1, 'b': 2}
Como se sugirió anteriormente, usar dos líneas o escribir una función es probablemente una mejor manera de hacerlo.
Sé que esto realmente no se ajusta a los detalles específicos de las preguntas ("one liner"), pero dado que ninguna de las respuestas anteriores fue en esta dirección, mientras que muchas respuestas abordaron el problema de rendimiento, sentí Debería aportar mis pensamientos.
Dependiendo del caso de uso, puede que no sea necesario crear un diccionario combinado "real" de los diccionarios de entrada dados. Una vista que hace esto puede ser suficiente en muchos casos, i. mi. un objeto que actúa como lo haría el diccionario combinado sin calcularlo por completo. Una versión perezosa del diccionario combinado, por así decirlo.
En Python, esto es bastante simple y se puede hacer con el código que se muestra al final de mi publicación. Esto dado, la respuesta a la pregunta original sería:
z = MergeDict(x, y)
Cuando se utiliza este nuevo objeto, se comportará como un diccionario combinado, pero tendrá un tiempo de creación constante y una huella de memoria constante, sin tocar los diccionarios originales. Crearlo es mucho más barato que en las otras soluciones propuestas.
Por supuesto, si usa mucho el resultado, en algún momento alcanzará el límite en el que crear un diccionario real fusionado hubiera sido la solución más rápida. Como dije, depende de su caso de uso.
Si alguna vez sintió que preferiría tener una dict
real fusionada, llamar a dict(z)
la produciría (pero, por supuesto, es mucho más costosa que las otras soluciones, por lo que vale la pena mencionarla).
También puede usar esta clase para hacer una especie de diccionario de copia en escritura:
a = { 'x': 3, 'y': 4 }
b = MergeDict(a) # we merge just one dict
b['x'] = 5
print b # will print {'x': 5, 'y': 4}
print a # will print {'y': 4, 'x': 3}
Aquí está el código directo de MergeDict
:
class MergeDict(object):
def __init__(self, *originals):
self.originals = ({},) + originals[::-1] # reversed
def __getitem__(self, key):
for original in self.originals:
try:
return original[key]
except KeyError:
pass
raise KeyError(key)
def __setitem__(self, key, value):
self.originals[0][key] = value
def __iter__(self):
return iter(self.keys())
def __repr__(self):
return '%s(%s)' % (
self.__class__.__name__,
', '.join(repr(original)
for original in reversed(self.originals)))
def __str__(self):
return '{%s}' % ', '.join(
'%r: %r' % i for i in self.iteritems())
def iteritems(self):
found = set()
for original in self.originals:
for k, v in original.iteritems():
if k not in found:
yield k, v
found.add(k)
def items(self):
return list(self.iteritems())
def keys(self):
return list(k for k, _ in self.iteritems())
def values(self):
return list(v for _, v in self.iteritems())
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = dict(x.items() + y.items())
print z
Para los elementos con claves en ambos diccionarios ('b'), puede controlar cuál termina en la salida colocando ese último.
Usando una comprensión dict, puede
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
dc = {xi:(x[xi] if xi not in list(y.keys())
else y[xi]) for xi in list(x.keys())+(list(y.keys()))}
Da
>>> dc
{'a': 1, 'c': 11, 'b': 10}
Tenga en cuenta la sintaxis para if else
en comprensión
{ (some_key if condition else default_key):(something_if_true if condition
else something_if_false) for key, value in dict_.items() }
En python3, el método items
ya no devuelve una lista, sino más bien una vista , que actúa como un conjunto. En este caso, deberá tomar la unión de conjunto ya que la concatenación con +
no funcionará:
dict(x.items() | y.items())
Para el comportamiento similar a python3 en la versión 2.7, el método viewitems
debería funcionar en lugar de items
:
dict(x.viewitems() | y.viewitems())
De todos modos, prefiero esta notación, ya que parece más natural pensar en ella como una operación de unión de conjuntos que como una concatenación (como muestra el título).
Editar:
Un par de puntos más para python 3. Primero, tenga en cuenta que el truco dict(x, **y)
no funcionará en python 3 a menos que las claves en y
sean cadenas.
Además, Raymond Hettinger's Chainmap answer es bastante elegante, ya que puede tomar un número arbitrario de dictados como argumentos, pero de los documentos parece que mira secuencialmente a través de una lista de todos los dictados para cada búsqueda:
Las búsquedas buscan las asignaciones subyacentes sucesivamente hasta que se encuentra una clave.
Esto puede ralentizarlo si tiene muchas búsquedas en su aplicación:
In [1]: from collections import ChainMap
In [2]: from string import ascii_uppercase as up, ascii_lowercase as lo; x = dict(zip(lo, up)); y = dict(zip(up, lo))
In [3]: chainmap_dict = ChainMap(y, x)
In [4]: union_dict = dict(x.items() | y.items())
In [5]: timeit for k in union_dict: union_dict[k]
100000 loops, best of 3: 2.15 µs per loop
In [6]: timeit for k in chainmap_dict: chainmap_dict[k]
10000 loops, best of 3: 27.1 µs per loop
Entonces, un orden de magnitud más lento para las búsquedas. Soy fanático de Chainmap, pero parece menos práctico donde puede haber muchas búsquedas.
Basándome en ideas aquí y en otros lugares, he comprendido una función:
def merge(*dicts, **kv):
return { k:v for d in list(dicts) + [kv] for k,v in d.items() }
Uso (probado en python 3):
assert (merge({1:11,'a':'aaa'},{1:99, 'b':'bbb'},foo='bar')==\
{1: 99, 'foo': 'bar', 'b': 'bbb', 'a': 'aaa'})
assert (merge(foo='bar')=={'foo': 'bar'})
assert (merge({1:11},{1:99},foo='bar',baz='quux')==\
{1: 99, 'foo': 'bar', 'baz':'quux'})
assert (merge({1:11},{1:99})=={1: 99})
Podrías usar una lambda en su lugar.
Es tan tonto que .update
no devuelve nada.
Solo uso una función auxiliar simple para resolver el problema:
def merge(dict1,*dicts):
for dict2 in dicts:
dict1.update(dict2)
return dict1
Ejemplos:
merge(dict1,dict2)
merge(dict1,dict2,dict3)
merge(dict1,dict2,dict3,dict4)
merge({},dict1,dict2) # this one returns a new copy
Si no te importa mutar x
,
x.update(y) or x
Simple, legible, performante. Usted sabe update()
siempre devuelve None
, que es un valor falso. Por lo tanto, la expresión anterior siempre se evaluará a x
, después de actualizarla.
Los métodos de mutación en la biblioteca estándar (como .update()
) devuelven None
por convención, por lo que este patrón también funcionará en esos. Si está utilizando un método que no sigue esta convención, entonces or
puede no funcionar. Pero, en su lugar, puede usar una visualización e índice de tuplas para convertirlo en una sola expresión. Esto funciona independientemente de lo que evalúa el primer elemento.
(x.update(y), x)[-1]
Si aún no tiene x
en una variable, puede usar lambda
para hacer un local sin usar una instrucción de asignación. Esto equivale a utilizar lambda
como let expression , que es una técnica común en lenguajes funcionales, pero que puede no ser pitónica.
(lambda x: x.update(y) or x)({'a': 1, 'b': 2})
Aunque no es tan diferente del siguiente uso del nuevo operador de morsa (solo Python 3.8+):
(x := {'a': 1, 'b': 2}).update(y) or x
Si desea una copia, el estilo PEP 448 es el más fácil {**x, **y}
. Pero si eso no está disponible en su versión de Python (anterior), el patrón let también funciona aquí.
(lambda z: z.update(y) or z)(x.copy())
(Eso es, por supuesto, equivalente a (z := x.copy()).update(y) or z
, pero si su versión de Python es lo suficientemente nueva para eso, entonces el estilo PEP 448 estará disponible).
def dict_merge(a, b):
c = a.copy()
c.update(b)
return c
new = dict_merge(old, extras)
Entre estas respuestas dudosas y dudosas, este brillante ejemplo es la única y única buena manera de fusionar los dictados en Python, ¡respaldado por el dictador de por vida Guido van Rossum ! Alguien más sugirió la mitad de esto, pero no lo puso en una función.
print dict_merge(
{'color':'red', 'model':'Mini'},
{'model':'Ferrari', 'owner':'Carl'})
Da:
{'color': 'red', 'owner': 'Carl', 'model': 'Ferrari'}
Actualización recursiva / profunda de un dict
def deepupdate(original, update):
"""
Recursively update a dict.
Subdict's won't be overwritten but also updated.
"""
for key, value in original.iteritems():
if key not in update:
update[key] = value
elif isinstance(value, dict):
deepupdate(value, update[key])
return update
Demostración:
pluto_original = {
'name': 'Pluto',
'details': {
'tail': True,
'color': 'orange'
}
}
pluto_update = {
'name': 'Pluutoo',
'details': {
'color': 'blue'
}
}
print deepupdate(pluto_original, pluto_update)
Salidas:
{
'name': 'Pluutoo',
'details': {
'color': 'blue',
'tail': True
}
}
Gracias rednaw por ediciones.
Aunque las respuestas fueron buenas para este diccionario superficial , ninguno de los métodos definidos aquí realmente hace una fusión profunda de diccionario.
Siguen ejemplos:
a = { 'one': { 'depth_2': True }, 'two': True }
b = { 'one': { 'extra': False } }
print dict(a.items() + b.items())
Uno esperaría un resultado de algo como esto:
{ 'one': { 'extra': False', 'depth_2': True }, 'two': True }
En cambio, obtenemos esto:
{'two': True, 'one': {'extra': False}}
La entrada 'one' debería haber tenido 'depth_2' y 'extra' como elementos dentro de su diccionario si realmente fuera una fusión.
Usar cadena también no funciona:
from itertools import chain
print dict(chain(a.iteritems(), b.iteritems()))
Resultados en:
{'two': True, 'one': {'extra': False}}
La profunda fusión que rcwesick dio también crea el mismo resultado.
Sí, funcionará fusionar los diccionarios de muestra, pero ninguno de ellos es un mecanismo genérico para fusionar. Actualizaré esto más adelante una vez que escriba un método que haga una verdadera fusión.
from collections import Counter
dict1 = {'a':1, 'b': 2}
dict2 = {'b':10, 'c': 11}
result = dict(Counter(dict1) + Counter(dict2))
Esto debería solucionar tu problema.
En su caso, lo que puede hacer es:
z = dict(x.items() + y.items())
Esto, como lo desee, pondrá el dict final en z
, y hará que el valor de la clave b
sea anulado correctamente por el valor del segundo (y
) dict:
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = dict(x.items() + y.items())
>>> z
{'a': 1, 'c': 11, 'b': 10}
Si usa Python 3, es solo un poco más complicado. Para crear z
:
>>> z = dict(list(x.items()) + list(y.items()))
>>> z
{'a': 1, 'c': 11, 'b': 10}
Abuso que conduce a una solución de una expresión para La respuesta de Matthew:
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = (lambda f=x.copy(): (f.update(y), f)[1])()
>>> z
{'a': 1, 'c': 11, 'b': 10}
Dijiste que querías una expresión, así que abusé de lambda
para unir un nombre y tuplas para anular el límite de una expresión de lambda. Siéntase libre de encogerse.
También podría hacer esto, por supuesto, si no le importa copiarlo:
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = (x.update(y), x)[1]
>>> z
{'a': 1, 'b': 10, 'c': 11}
(Solo para Python2.7 *; existen soluciones más simples para Python3 *.)
Si no eres reacio a importar un módulo de biblioteca estándar, puedes hacer
from functools import reduce
def merge_dicts(*dicts):
return reduce(lambda a, d: a.update(d) or a, dicts, {})
(El bit or a
en lambda
es necesario porque dict.update
siempre devuelve None
en caso de éxito).
Si bien la pregunta ya ha sido respondida varias veces, esta solución simple al problema aún no se ha enumerado.
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z4 = {}
z4.update(x)
z4.update(y)
Es tan rápido como z0 y el malvado z2 mencionado anteriormente, pero es fácil de entender y cambiar.
Una alternativa:
z = x.copy()
z.update(y)
En Python 3.0 y versiones posteriores , puede usar { {X0}} que agrupa varios dictados u otras asignaciones para crear una vista única y actualizable:
>>> from collections import ChainMap
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = ChainMap({}, y, x)
>>> for k, v in z.items():
print(k, '-->', v)
a --> 1
b --> 10
c --> 11
Actualización para Python 3.5 y posterior : puede usar PEP 448 diccionario ampliado de empaquetado y desempaquetado. Esto es rápido y fácil:
>>> x = {'a':1, 'b': 2}
>>> y = y = {'b':10, 'c': 11}
>>> {**x, **y}
{'a': 1, 'b': 10, 'c': 11}
Dos diccionarios
def union2(dict1, dict2):
return dict(list(dict1.items()) + list(dict2.items()))
n diccionarios
def union(*dicts):
return dict(itertools.chain.from_iterable(dct.items() for dct in dicts))
sum
tiene un mal rendimiento. Ver https://mathieularose.com/how -not-to-flatten-a-list-of-lists-in-python /
Solución simple usando itertools que preserva el orden (los últimos dictados tienen prioridad)
import itertools as it
merge = lambda *args: dict(it.chain.from_iterable(it.imap(dict.iteritems, args)))
Y es uso:
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> merge(x, y)
{'a': 1, 'b': 10, 'c': 11}
>>> z = {'c': 3, 'd': 4}
>>> merge(x, y, z)
{'a': 1, 'b': 10, 'c': 3, 'd': 4}
Probablemente esta no sea una respuesta popular, pero es casi seguro que no desea hacerlo. Si desea una copia que sea una fusión, use copy (o deepcopy, dependiendo en lo que quieres) y luego actualiza. Las dos líneas de código son mucho más legibles, más Pythonic, que la creación de una sola línea con .items () + .items (). Explícito es mejor que implícito.
Además, cuando usa .items () (pre Python 3.0), está creando una nueva lista que contiene los elementos del dict. Si sus diccionarios son grandes, entonces eso es bastante sobrecarga (dos grandes listas que se desecharán tan pronto como se cree el dict combinado). update () puede funcionar de manera más eficiente, ya que puede ejecutarse a través del segundo dict ítem por ítem.
En términos de time:
>>> timeit.Timer("dict(x, **y)", "x = dict(zip(range(1000), range(1000)))\ny=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000)
15.52571702003479
>>> timeit.Timer("temp = x.copy()\ntemp.update(y)", "x = dict(zip(range(1000), range(1000)))\ny=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000)
15.694622993469238
>>> timeit.Timer("dict(x.items() + y.items())", "x = dict(zip(range(1000), range(1000)))\ny=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000)
41.484580039978027
En mi opinión, la pequeña desaceleración entre los dos primeros vale la pena por la legibilidad. Además, los argumentos de palabras clave para la creación del diccionario solo se agregaron en Python 2.3, mientras que copy () y update () funcionarán en versiones anteriores.
El problema que tengo con las soluciones enumeradas hasta la fecha es que, en el diccionario combinado, el valor de la clave "b" es 10 pero, a mi modo de ver, debería ser 12. En ese sentido, presento lo siguiente:
import timeit
n=100000
su = """
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
"""
def timeMerge(f,su,niter):
print "{:4f} sec for: {:30s}".format(timeit.Timer(f,setup=su).timeit(n),f)
timeMerge("dict(x, **y)",su,n)
timeMerge("x.update(y)",su,n)
timeMerge("dict(x.items() + y.items())",su,n)
timeMerge("for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k] ",su,n)
#confirm for loop adds b entries together
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k]
print "confirm b elements are added:",x
Resultados:
0.049465 sec for: dict(x, **y)
0.033729 sec for: x.update(y)
0.150380 sec for: dict(x.items() + y.items())
0.083120 sec for: for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k]
confirm b elements are added: {'a': 1, 'c': 11, 'b': 12}
Python 3.5 (PEP 448) permite una mejor opción de sintaxis:
x = {'a': 1, 'b': 1}
y = {'a': 2, 'c': 2}
final = {**x, **y}
final
# {'a': 2, 'b': 1, 'c': 2}
O incluso
final = {'a': 1, 'b': 1, **x, **y}
Quería algo similar, pero con la capacidad de especificar cómo se fusionaron los valores en las claves duplicadas, así que lo pirateé (pero no lo probé en gran medida). Obviamente, esta no es una sola expresión, pero es una llamada de función única.
def merge(d1, d2, merge_fn=lambda x,y:y):
"""
Merges two dictionaries, non-destructively, combining
values on duplicate keys as defined by the optional merge
function. The default behavior replaces the values in d1
with corresponding values in d2. (There is no other generally
applicable merge strategy, but often you'll have homogeneous
types in your dicts, so specifying a merge technique can be
valuable.)
Examples:
>>> d1
{'a': 1, 'c': 3, 'b': 2}
>>> merge(d1, d1)
{'a': 1, 'c': 3, 'b': 2}
>>> merge(d1, d1, lambda x,y: x+y)
{'a': 2, 'c': 6, 'b': 4}
"""
result = dict(d1)
for k,v in d2.iteritems():
if k in result:
result[k] = merge_fn(result[k], v)
else:
result[k] = v
return result
Esto se puede hacer con una sola comprensión dict:
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> { key: y[key] if key in y else x[key]
for key in set(x) + set(y)
}
En mi opinión, la mejor respuesta para la parte de 'expresión única' ya que no se necesitan funciones adicionales, y es breve.
La mejor versión que podría pensar mientras no uso copia sería:
from itertools import chain
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
dict(chain(x.iteritems(), y.iteritems()))
Es más rápido que dict(x.items() + y.items())
pero no tan rápido como n = copy(a); n.update(b)
, al menos en CPython. Esta versión también funciona en Python 3 si cambia iteritems()
a items()
, que se realiza automáticamente con la herramienta 2to3.
Personalmente, me gusta más esta versión porque describe bastante bien lo que quiero en una única sintaxis funcional. El único problema menor es que no es completamente obvio que los valores de y tienen prioridad sobre los valores de x, pero no creo que sea difícil de resolver.
Sé pitónico. Utilice una comprensión:
z={i:d[i] for d in [x,y] for i in d}
>>> print z
{'a': 1, 'c': 11, 'b': 10}
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> x, z = dict(x), x.update(y) or x
>>> x
{'a': 1, 'b': 2}
>>> y
{'c': 11, 'b': 10}
>>> z
{'a': 1, 'c': 11, 'b': 10}
Otra opción más concisa:
z = dict(x, **y)
Nota : esta se ha convertido en una respuesta popular, pero es importante señalar que si y
tiene teclas que no son de cadena, el hecho de que esto funcione es un abuso de un CPython detalle de implementación, y no funciona en Python 3, ni en PyPy, IronPython o Jython. Además, Guido no es fanático. Por lo tanto, no puedo recomendar esta técnica para el código portátil compatible con versiones posteriores o de implementación cruzada, lo que realmente significa que debe evitarse por completo.
En una respuesta de seguimiento, usted preguntó sobre el rendimiento relativo de estas dos alternativas:
z1 = dict(x.items() + y.items())
z2 = dict(x, **y)
En mi máquina, al menos (un x86_64 bastante común que ejecuta Python 2.5.2), la alternativa z2
no solo es más corta y simple, sino también significativamente más rápida. Puede verificar esto usted mismo utilizando el módulo timeit
que viene con Python.
Ejemplo 1: diccionarios idénticos que asignan 20 enteros consecutivos a sí mismos:
% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z1=dict(x.items() + y.items())'
100000 loops, best of 3: 5.67 usec per loop
% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z2=dict(x, **y)'
100000 loops, best of 3: 1.53 usec per loop
z2
gana por un factor de 3.5 más o menos. Parece que diferentes diccionarios producen resultados bastante diferentes, pero z2
siempre parece salir adelante. (Si obtiene resultados inconsistentes para la prueba same , intente pasar -r
con un número mayor que el predeterminado 3.)
Ejemplo 2: diccionarios no superpuestos que asignan 252 cadenas cortas a enteros y viceversa:
% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z1=dict(x.items() + y.items())'
1000 loops, best of 3: 260 usec per loop
% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z2=dict(x, **y)'
10000 loops, best of 3: 26.9 usec per loop
z2
gana por un factor de 10. ¡Esa es una gran victoria en mi libro!
Después de comparar esos dos, me preguntaba si el bajo rendimiento de z1
podría atribuirse a la sobrecarga de construir las dos listas de elementos, lo que a su vez me llevó a preguntarme si esta variación podría funcionar mejor:
from itertools import chain
z3 = dict(chain(x.iteritems(), y.iteritems()))
Algunas pruebas rápidas, p.
% python -m timeit -s 'from itertools import chain; from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z3=dict(chain(x.iteritems(), y.iteritems()))'
10000 loops, best of 3: 66 usec per loop
Llévame a la conclusión de que z3
es algo más rápido que z1
, pero no tan rápido como z2
. Definitivamente no vale la pena todo el tipeo adicional.
A esta discusión todavía le falta algo importante, que es una comparación de rendimiento de estas alternativas con la forma "obvia" de fusionar dos listas: usando el método update
. Para tratar de mantener las cosas en pie de igualdad con las expresiones, ninguna de las cuales modifica x o y, voy a hacer una copia de x en lugar de modificarla en su lugar, de la siguiente manera:
z0 = dict(x)
z0.update(y)
Un resultado típico:
% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z0=dict(x); z0.update(y)'
10000 loops, best of 3: 26.9 usec per loop
En otras palabras, z0
y z2
parecen tener un rendimiento esencialmente idéntico. ¿Crees que esto podría ser una coincidencia? Yo no....
De hecho, iría tan lejos como para afirmar que es imposible para el código Python puro hacer algo mejor que esto. Y si puede hacerlo significativamente mejor en un módulo de extensión C, imagino que la gente de Python podría estar interesada en incorporar su código (o una variación de su enfoque) en el núcleo de Python. Python usa dict
en muchos lugares; optimizar sus operaciones es un gran problema.
También podrías escribir esto como
z0 = x.copy()
z0.update(y)
Como lo hace Tony, pero (no es sorprendente) la diferencia en la notación resulta no tener ningún efecto medible en el rendimiento. Use lo que le parezca más adecuado. Por supuesto, tiene toda la razón al señalar que la versión de dos afirmaciones es mucho más fácil de entender.
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.