J'ai deux dictionnaires Python, et je veux écrire une seule expression qui renvoie ces deux dictionnaires, fusionnés. La méthode update() serait ce dont j'ai besoin, si elle renvoyait son résultat au lieu de modifier un dictionnaire sur place.

>>> x = {'a': 1, 'b': 2}
>>> y = {'b': 10, 'c': 11}
>>> z = x.update(y)
>>> print(z)
None
>>> x
{'a': 1, 'b': 10, 'c': 11}

Comment puis-je obtenir ce dictionnaire fusionné final dans z, pas x?

(Pour plus de clarté, le dernier qui gagne la gestion des conflits de dict.update() est également ce que je recherche.)

4573
Carl Meyer 2 sept. 2008 à 11:44

29 réponses

Si vous pensez que les lambdas sont mauvais, ne lisez pas plus loin. Comme demandé, vous pouvez écrire la solution rapide et efficace en mémoire avec une seule expression:

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}

Comme suggéré ci-dessus, utiliser deux lignes ou écrire une fonction est probablement une meilleure solution.

37
EMS 23 nov. 2011 à 18:20
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = dict(x.items() + y.items())
print z

Pour les éléments avec des clés dans les deux dictionnaires («b»), vous pouvez contrôler celui qui se retrouve dans la sortie en mettant celui-ci en dernier.

58
Greg Hewgill 2 sept. 2008 à 07:49

En utilisant une compréhension de dict, vous pouvez

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()))}

Donne

>>> dc
{'a': 1, 'c': 11, 'b': 10}

Notez la syntaxe de if else dans la compréhension

{ (some_key if condition else default_key):(something_if_true if condition 
          else something_if_false) for key, value in dict_.items() }
5
kiriloff 27 mai 2013 à 09:04

En python3, la méthode items ne renvoie plus une liste, mais plutôt une vue , qui agit comme un ensemble. Dans ce cas, vous devrez prendre l'union définie car la concaténation avec + ne fonctionnera pas:

dict(x.items() | y.items())

Pour un comportement semblable à python3 dans la version 2.7, la méthode viewitems devrait fonctionner à la place de items:

dict(x.viewitems() | y.viewitems())

Je préfère de toute façon cette notation car il semble plus naturel de la considérer comme une opération d'union d'ensemble plutôt que comme une concaténation (comme le titre le montre).

Modifier:

Quelques points supplémentaires pour python 3. Tout d'abord, notez que l'astuce dict(x, **y) ne fonctionnera pas en python 3 à moins que les clés de y soient des chaînes.

En outre, la chaîne de Raymond Hettinger réponse est assez élégante, car elle peut prendre un nombre arbitraire de dict comme arguments, mais à partir des documents il semble qu'il examine séquentiellement une liste de tous les dict pour chaque recherche:

Les recherches recherchent successivement les mappages sous-jacents jusqu'à ce qu'une clé soit trouvée.

Cela peut vous ralentir si vous avez beaucoup de recherches dans votre application:

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

Donc, environ un ordre de grandeur plus lent pour les recherches. Je suis un fan de Chainmap, mais semble moins pratique où il peut y avoir de nombreuses recherches.

29
Community 23 mai 2017 à 12:34

En m'appuyant sur des idées ici et ailleurs, j'ai compris une fonction:

def merge(*dicts, **kv): 
      return { k:v for d in list(dicts) + [kv] for k,v in d.items() }

Utilisation (testé 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})

Vous pouvez utiliser un lambda à la place.

10
Bijou Trouvaille 19 juil. 2013 à 05:49

C'est tellement idiot que .update ne retourne rien.
J'utilise simplement une fonction d'assistance simple pour résoudre le problème:

def merge(dict1,*dicts):
    for dict2 in dicts:
        dict1.update(dict2)
    return dict1

Exemples:

merge(dict1,dict2)
merge(dict1,dict2,dict3)
merge(dict1,dict2,dict3,dict4)
merge({},dict1,dict2)  # this one returns a new copy
7
GetFree 2 mars 2014 à 01:44

Si cela ne vous dérange pas de muter x,

x.update(y) or x

Simple, lisible, performant. Vous savez update() renvoie toujours None, qui est une fausse valeur. Ainsi, l'expression ci-dessus sera toujours évaluée à x, après sa mise à jour.

Les méthodes de mutation dans la bibliothèque standard (comme .update()) retournent None par convention, donc ce modèle fonctionnera aussi sur celles-ci. Si vous utilisez une méthode qui ne respecte pas cette convention, alors or peut ne pas fonctionner. Mais, vous pouvez utiliser un affichage et un index de tuple pour en faire une seule expression à la place. Cela fonctionne quel que soit le premier élément évalué.

(x.update(y), x)[-1]

Si vous n'avez pas encore x dans une variable, vous pouvez utiliser lambda pour créer un local sans utiliser une instruction d'affectation. Cela revient à utiliser lambda comme expression let , qui est une technique courante dans les langages fonctionnels, mais peut-être non-pythonique.

(lambda x: x.update(y) or x)({'a': 1, 'b': 2})

Bien que ce ne soit pas si différent de l'utilisation suivante du nouvel opérateur morse (Python 3.8+ uniquement):

(x := {'a': 1, 'b': 2}).update(y) or x

Si vous voulez une copie, le style PEP 448 est le plus simple {**x, **y}. Mais si ce n'est pas disponible dans votre (ancienne) version Python, le modèle let fonctionne ici aussi.

(lambda z: z.update(y) or z)(x.copy())

(C'est, bien sûr, équivalent à (z := x.copy()).update(y) or z, mais si votre version Python est suffisamment nouvelle pour cela, alors le style PEP 448 sera disponible.)

8
gilch 17 janv. 2020 à 06:00
def dict_merge(a, b):
  c = a.copy()
  c.update(b)
  return c

new = dict_merge(old, extras)

Parmi ces réponses louches et douteuses, cet exemple brillant est le seul et unique bon moyen de fusionner des dict en Python, approuvé par le dictateur à vie Guido van Rossum lui-même! Quelqu'un d'autre a suggéré la moitié de cela, mais ne l'a pas mis dans une fonction.

print dict_merge(
      {'color':'red', 'model':'Mini'},
      {'model':'Ferrari', 'owner':'Carl'})

Donne:

{'color': 'red', 'owner': 'Carl', 'model': 'Ferrari'}
46
Sam Watkins 6 août 2012 à 09:30

Mettre à jour récursivement / en profondeur 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

Manifestation:

pluto_original = {
    'name': 'Pluto',
    'details': {
        'tail': True,
        'color': 'orange'
    }
}

pluto_update = {
    'name': 'Pluutoo',
    'details': {
        'color': 'blue'
    }
}

print deepupdate(pluto_original, pluto_update)

Les sorties:

{
    'name': 'Pluutoo',
    'details': {
        'color': 'blue',
        'tail': True
    }
}

Merci rednaw pour les modifications.

84
Dawid Gosławski 18 déc. 2015 à 11:19

Même si les réponses étaient bonnes pour ce dictionnaire superficiel , aucune des méthodes définies ici ne fait réellement une fusion de dictionnaire approfondie.

Voici des exemples:

a = { 'one': { 'depth_2': True }, 'two': True }
b = { 'one': { 'extra': False } }
print dict(a.items() + b.items())

On pourrait s'attendre à un résultat de quelque chose comme ceci:

{ 'one': { 'extra': False', 'depth_2': True }, 'two': True }

Au lieu de cela, nous obtenons ceci:

{'two': True, 'one': {'extra': False}}

L'entrée «one» aurait dû avoir «depth_2» et «extra» comme éléments dans son dictionnaire si c'était vraiment une fusion.

L'utilisation de la chaîne ne fonctionne pas non plus:

from itertools import chain
print dict(chain(a.iteritems(), b.iteritems()))

Résulte en:

{'two': True, 'one': {'extra': False}}

La fusion profonde que rcwesick a donnée crée également le même résultat.

Oui, cela fonctionnera pour fusionner les exemples de dictionnaires, mais aucun d'entre eux n'est un mécanisme générique pour fusionner. Je le mettrai à jour plus tard une fois que j'écrirai une méthode qui effectue une véritable fusion.

16
Thanh Lim 3 août 2012 à 23:36
from collections import Counter
dict1 = {'a':1, 'b': 2}
dict2 = {'b':10, 'c': 11}
result = dict(Counter(dict1) + Counter(dict2))

Cela devrait résoudre votre problème.

10
reetesh11 30 nov. 2015 à 13:04

Dans votre cas, vous pouvez:

z = dict(x.items() + y.items())

Cela, comme vous le souhaitez, mettra le dict final dans z et fera en sorte que la valeur de la clé b soit correctement remplacée par la deuxième (y) valeur du 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 vous utilisez Python 3, c'est seulement un peu plus compliqué. Pour créer z:

>>> z = dict(list(x.items()) + list(y.items()))
>>> z
{'a': 1, 'c': 11, 'b': 10}
1587
wim 29 août 2018 à 17:18

Abus menant à une solution à une expression pour la réponse 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}

Vous avez dit que vous vouliez une expression, j'ai donc abusé de lambda pour lier un nom et des tuples pour remplacer la limite d'une expression de lambda. N'hésitez pas à grincer des dents.

Vous pouvez également le faire bien sûr si vous ne vous souciez pas de le copier:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = (x.update(y), x)[1]
>>> z
{'a': 1, 'b': 10, 'c': 11}
22
Community 23 mai 2017 à 12:34

(Pour Python2.7 * uniquement; il existe des solutions plus simples pour Python3 *.)

Si vous n'êtes pas opposé à l'importation d'un module de bibliothèque standard, vous pouvez le faire

from functools import reduce

def merge_dicts(*dicts):
    return reduce(lambda a, d: a.update(d) or a, dicts, {})

(Le bit or a dans le lambda est nécessaire car dict.update renvoie toujours None en cas de succès.)

11
kjo 28 mars 2016 à 13:13

Bien que la question ait déjà reçu plusieurs réponses, cette solution simple au problème n'a pas encore été répertoriée.

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z4 = {}
z4.update(x)
z4.update(y)

Il est aussi rapide que z0 et le mal z2 mentionné ci-dessus, mais facile à comprendre et à changer.

47
phobie 14 oct. 2011 à 16:12

Une alternative:

z = x.copy()
z.update(y)
620
Matthew Schinckel 2 sept. 2008 à 13:00

Dans Python 3.0 et versions ultérieures , vous pouvez utiliser { {X0}} qui regroupe plusieurs dictés ou autres mappages pour créer une vue unique et modifiable:

>>> 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

Mise à jour pour Python 3.5 et versions ultérieures : vous pouvez utiliser PEP 448 extension et décompression du dictionnaire étendu. C'est simple et rapide:

>>> x = {'a':1, 'b': 2}
>>> y = y = {'b':10, 'c': 11}
>>> {**x, **y}
{'a': 1, 'b': 10, 'c': 11}
112
Neuron 20 nov. 2019 à 17:03

Deux dictionnaires

def union2(dict1, dict2):
    return dict(list(dict1.items()) + list(dict2.items()))

Dictionnaires n

def union(*dicts):
    return dict(itertools.chain.from_iterable(dct.items() for dct in dicts))

sum a de mauvaises performances. Voir https://mathieularose.com/how -pas aplatir-une-liste-de-listes-en-python /

21
Mathieu Larose 2 oct. 2016 à 18:16

Solution simple utilisant itertools qui préserve l'ordre (les derniers dits ont priorité)

import itertools as it
merge = lambda *args: dict(it.chain.from_iterable(it.imap(dict.iteritems, args)))

Et c'est son utilisation:

>>> 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}
21
reubano 6 sept. 2016 à 11:30

Ce ne sera probablement pas une réponse populaire, mais vous ne voulez certainement pas faire cela. Si vous souhaitez une copie qui est une fusion, utilisez alors la copie (ou deepcopy, selon sur ce que vous voulez), puis mettez à jour. Les deux lignes de code sont beaucoup plus lisibles - plus Pythonic - que la création d'une seule ligne avec .items () + .items (). Explicite vaut mieux qu'implicite.

De plus, lorsque vous utilisez .items () (avant Python 3.0), vous créez une nouvelle liste qui contient les éléments du dict. Si vos dictionnaires sont volumineux, cela représente beaucoup de frais généraux (deux grandes listes qui seront supprimées dès que le dict fusionné sera créé). update () peut fonctionner plus efficacement, car il peut parcourir le deuxième dict élément par élément.

En termes de temps:

>>> 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

IMO le minuscule ralentissement entre les deux premiers en vaut la peine pour la lisibilité. De plus, les arguments de mots clés pour la création de dictionnaire n'ont été ajoutés qu'en Python 2.3, tandis que copy () et update () fonctionneront dans les anciennes versions.

207
twasbrillig 5 août 2014 à 23:56

Le problème que j'ai avec les solutions répertoriées à ce jour est que, dans le dictionnaire fusionné, la valeur de la clé "b" est 10 mais, à mon avis, elle devrait être 12. Dans cette optique, je présente ce qui suit:

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

Résultats:

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}
10
upandacross 3 déc. 2013 à 18:11

Python 3.5 (PEP 448) permet une option de syntaxe plus agréable:

x = {'a': 1, 'b': 1}
y = {'a': 2, 'c': 2}
final = {**x, **y} 
final
# {'a': 2, 'b': 1, 'c': 2}

Ou même

final = {'a': 1, 'b': 1, **x, **y}
64
Bilal Syed Hussain 26 févr. 2015 à 21:27

Je voulais quelque chose de similaire, mais avec la possibilité de spécifier comment les valeurs des clés en double ont été fusionnées, j'ai donc piraté cela (mais je ne l'ai pas testé de manière intensive). Évidemment, ce n'est pas une expression unique, mais c'est un appel de fonction unique.

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
110
Rainy 13 sept. 2014 à 19:56

Cela peut être fait avec une seule compréhension de 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)
    }

À mon avis, la meilleure réponse pour la partie «expression unique» car aucune fonction supplémentaire n'est nécessaire, et elle est courte.

9
RemcoGerlich 17 juil. 2015 à 14:47

La meilleure version que je pourrais penser sans utiliser de copie serait:

from itertools import chain
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
dict(chain(x.iteritems(), y.iteritems()))

C'est plus rapide que dict(x.items() + y.items()) mais pas aussi rapide que n = copy(a); n.update(b), du moins sur CPython. Cette version fonctionne également en Python 3 si vous remplacez iteritems() par items(), ce qui est automatiquement effectué par l'outil 2to3.

Personnellement, je préfère cette version car elle décrit assez bien ce que je veux dans une seule syntaxe fonctionnelle. Le seul problème mineur est qu'il ne rend pas complètement évident que les valeurs de y ont priorité sur les valeurs de x, mais je ne pense pas qu'il soit difficile de comprendre cela.

69
driax 14 oct. 2010 à 18:55

Soyez pythonique. Utilisez une compréhension:

z={i:d[i] for d in [x,y] for i in d}

>>> print z
{'a': 1, 'c': 11, 'b': 10}
32
Robino 29 sept. 2016 à 10:45
>>> 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}
8
John La Rooy 13 nov. 2013 à 10:01

Une autre option, plus concise:

z = dict(x, **y)

Remarque : cela est devenu une réponse populaire, mais il est important de souligner que si y a des clés autres que des chaînes, le fait que cela fonctionne est un abus de CPython détail d'implémentation, et il ne fonctionne pas dans Python 3, ni dans PyPy, IronPython ou Jython. De plus, Guido n'est pas un fan. Je ne peux donc pas recommander cette technique pour le code portable à compatibilité ascendante ou à implémentation croisée, ce qui signifie vraiment qu'elle doit être évitée complètement.

331
Carl Meyer 21 janv. 2016 à 06:43

Dans une réponse de suivi, vous avez posé des questions sur les performances relatives de ces deux alternatives:

z1 = dict(x.items() + y.items())
z2 = dict(x, **y)

Sur ma machine, au moins (un x86_64 assez ordinaire exécutant Python 2.5.2), l'alternative z2 est non seulement plus courte et plus simple mais aussi beaucoup plus rapide. Vous pouvez le vérifier par vous-même à l'aide du module timeit fourni avec Python.

Exemple 1: dictionnaires identiques mappant 20 entiers consécutifs sur eux-mêmes:

% 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 gagne par un facteur de 3,5 environ. Différents dictionnaires semblent donner des résultats assez différents, mais z2 semble toujours l'emporter. (Si vous obtenez des résultats incohérents pour le même test, essayez de passer -r avec un nombre supérieur au 3. par défaut.)

Exemple 2: dictionnaires sans chevauchement mappant 252 chaînes courtes en entiers et vice versa:

% 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 gagne par un facteur d'environ 10. C'est une très grosse victoire dans mon livre!

Après avoir comparé ces deux éléments, je me suis demandé si les mauvaises performances de z1 pouvaient être attribuées aux frais généraux liés à la construction des deux listes d'éléments, ce qui m'a amené à me demander si cette variation pourrait mieux fonctionner:

from itertools import chain
z3 = dict(chain(x.iteritems(), y.iteritems()))

Quelques tests rapides, par ex.

% 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

Amène-moi à conclure que z3 est un peu plus rapide que z1, mais pas aussi vite que z2. Certainement pas la peine de taper tous les caractères supplémentaires.

Il manque encore quelque chose d'important à cette discussion, qui est une comparaison des performances de ces alternatives avec la manière "évidente" de fusionner deux listes: en utilisant la méthode update. Pour essayer de garder les choses sur un pied d'égalité avec les expressions, dont aucune ne modifie x ou y, je vais faire une copie de x au lieu de la modifier en place, comme suit:

z0 = dict(x)
z0.update(y)

Un résultat typique:

% 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 d'autres termes, z0 et z2 semblent avoir des performances essentiellement identiques. Pensez-vous que cela pourrait être une coïncidence? Je ne....

En fait, j'irais jusqu'à prétendre qu'il est impossible pour le code Python pur de faire mieux que cela. Et si vous pouvez faire beaucoup mieux dans un module d'extension C, j'imagine que les gens de Python pourraient bien être intéressés à incorporer votre code (ou une variation de votre approche) dans le noyau Python. Python utilise dict à de nombreux endroits; l'optimisation de ses opérations est un gros problème.

Vous pouvez également écrire ceci comme

z0 = x.copy()
z0.update(y)

Comme Tony le fait, mais (sans surprise) la différence de notation se révèle n'avoir aucun effet mesurable sur les performances. Utilisez celui qui vous convient. Bien sûr, il a absolument raison de souligner que la version à deux déclarations est beaucoup plus facile à comprendre.

143
the Tin Man 10 janv. 2015 à 02:32
38987