Soru Tek bir ifadede iki sözlük nasıl birleştirilir?


İki Python sözlükim var ve birleştirilmiş iki sözlüğü döndüren tek bir ifade yazmak istiyorum. update() Metodu, ihtiyacım olan şey olurdu, eğer yerinde bir dict'i değiştirmek yerine sonucunu döndürürse.

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

Bu son birleştirilmiş dict'ı nasıl alabilirim? z, değil x?

(Ekstra açık olmak gerekirse, son bir-birleşik çatışma-ele dict.update() ben de aradığım şey.)


3222
2017-09-02 07:44


Menşei




Cevaplar:


İki Python sözlüklerini tek bir ifadede nasıl birleştirebilirim?

Sözlükler için x ve y, z değerleri içeren birleştirilmiş bir sözlük haline gelir. y bunları değiştirmek x.

  • Python 3.5 veya daha büyük,

    z = {**x, **y}
    w = {'foo': 'bar', 'baz': 'qux', **y}  # merge a dict with literal values
    
  • Python 2'de (veya 3.4 veya daha düşük) bir işlev yazınız:

    def merge_two_dicts(x, y):
        z = x.copy()   # start with x's keys and values
        z.update(y)    # modifies z with y's keys and values & returns None
        return z
    

    ve

    z = merge_two_dicts(x, y)
    

açıklama

İki diksiyonunuz olduğunu ve bunları orijinal dikte değiştirmeden yeni bir dict ile birleştirmek istediğinizi varsayalım:

x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}

İstenen sonuç yeni bir sözlük almaktır (z) birleştirilen değerler ve ikinci dict'ın değerleri ilkinden gelen değerlerin üzerine yazılır.

>>> z
{'a': 1, 'b': 3, 'c': 4}

Bunun için önerilen yeni bir sözdizimi PEP 448 ve Python 3.5 olarak mevcut,

z = {**x, **y}

Ve bu gerçekten tek bir ifadedir. Şu anda uygulanan olarak gösteriliyor 3.5, PEP 478 için yayın planıve şimdi içine girmiştir Python 3.5'deki Yenilikler belgesi.

Ancak, birçok organizasyon hala Python 2'de olduğundan, bunu geriye dönük olarak yapmak isteyebilirsiniz. Python 2 ve Python 3.0-3.4'te bulunan klasik Pythonic yöntemi, bunu iki aşamalı bir işlem olarak yapmaktır:

z = x.copy()
z.update(y) # which returns None since it mutates z

Her iki yaklaşımda, y ikinci gelecek ve onun değerleri yerini alacak xdeğerleri 'b' işaret edecek 3 bizim nihai sonuçta.

Henüz Python 3.5 değil, ama bir tek ifade

Henüz Python 3.5'te değilseniz veya geriye dönük uyumlu bir kod yazmanız gerekiyorsa ve bunu bir tek ifadeEn doğru olanı ise doğru yaklaşım ise bir fonksiyona sokmaktır:

def merge_two_dicts(x, y):
    """Given two dicts, merge them into a new dict as a shallow copy."""
    z = x.copy()
    z.update(y)
    return z

ve sonra tek bir ifadeniz var:

z = merge_two_dicts(x, y)

Ayrıca, tanımlanmamış sayıda noktayı sıfırdan çok büyük bir sayıya birleştiren bir işlev de oluşturabilirsiniz:

def merge_dicts(*dict_args):
    """
    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in latter dicts.
    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result

Bu işlev, tüm dict'lar için Python 2 ve 3'te çalışacaktır. Örneğin. verilen dicts a için g:

z = merge_dicts(a, b, c, d, e, f, g) 

ve anahtar değer çiftleri g Dicts karşısında öncelik alacak a için f, ve bunun gibi.

Diğer Cevapların Eleştirileri

Eskiden kabul edilen cevapta gördüklerinizi kullanmayın:

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

Python 2'de, her bir dict için hafızada iki liste oluşturursunuz, ilk iki kondisyonun uzunluğuna eşit uzunlukta bir bellekte üçüncü bir liste oluşturursunuz ve daha sonra bu üç listeyi de dikte oluşturmak için atın. Python 3'te bu başarısız olur. çünkü iki tane ekliyorsun dict_items birlikte nesneleri, iki liste değil -

>>> c = dict(a.items() + b.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'dict_items' and 'dict_items'

ve bunları açık bir şekilde listeler olarak oluşturmalısınız, ör. z = dict(list(x.items()) + list(y.items())). Bu, kaynakların ve hesaplama gücünün kaybıdır.

Benzer şekilde, birliği almak items()Python 3'te (viewitems() Python 2.7'de), değerler paylaşılmayan nesneler olduğunda (örneğin, listeler gibi) başarısız olur. Değerleriniz yıkanabilir olsa bile, kümeler semantik olarak sırasız olduğundan, davranış önceliğe göre tanımlanmamıştır. Yani bunu yapma:

>>> c = dict(a.items() | b.items())

Bu örnek, değerler inkar edilemez olduğunda ne olduğunu gösterir:

>>> x = {'a': []}
>>> y = {'b': []}
>>> dict(x.items() | y.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

İşte bir önceliğe sahip olması gereken bir örnek, ancak bunun yerine x'in değeri, rastgele sıralama kümeleri nedeniyle korunur:

>>> x = {'a': 2}
>>> y = {'a': 1}
>>> dict(x.items() | y.items())
{'a': 2}

Kullanmaması gereken başka bir hack:

z = dict(x, **y)

Bu kullanır dict kurucu, ve çok hızlı ve hafıza açısından verimli (iki aşamalı sürecimizden biraz daha fazla) ama tam olarak burada ne olup bittiğini bilmedikçe (yani, dict kurucusuna anahtar kelime argümanları olarak geçiliyorsa), Okuması zor, amaçlanan kullanım değil, bu yüzden Pythonic değil.

İşte kullanımın bir örneği django'da düzeltildi.

Dicts, yıkanabilir tuşları (örneğin, frozensets veya tuples) almayı amaçlamaktadır, fakat Anahtarlar dizeler olmadığında bu yöntem Python 3'te başarısız olur.

>>> c = dict(a, **b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: keyword arguments must be strings

İtibaren mail listesiDilin yaratıcısı Guido van Rossum şunları yazdı:

Ben iyiyim   Dict ({}, ** {1: 3}) beyanı yasadışıdır, çünkü her şeyden önce   mekanizma.

ve

Görünüşe göre dict (x, ** y) "arama için" "cool hack" olarak dolaşıyor   x.update (y) ve x döndürün. ”Şahsen onu daha da aşağılayıcı buluyorum.   güzel.

Benim anlayışım (aynı zamanda dilin yaratıcısıamaçlanan kullanım için dict(**y) okunabilirlik amaçları için dikmeler oluşturmak içindir, örn .:

dict(a=1, b=10, c=11)

yerine

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

Yorumlara yanıt

Guido'nun söylediğine rağmen, dict(x, **y) btw dict belirtimiyle uyumludur. Hem Python 2 hem de 3 için çalışır. Bunun sadece dize anahtarları için çalıştığı gerçeği, anahtar kelime parametrelerinin nasıl çalıştığının doğrudan bir sonucudur ve kısa bir dict komutu değildir. Buradaki ** operatörü de bu mekanizmayı kötüye kullanmadığı gibi aslında **, anahtar kelimeleri anahtar kelimelere geçirecek şekilde tasarlanmıştır.

Yine, tuşlar dizisiz olduğunda 3 için çalışmaz. Gizli çağrı sözleşmesi, ad alanlarının sıradan diktiler almasıdır, ancak kullanıcılar yalnızca dizeleri olan anahtar kelime argümanlarını geçmelidir. Diğer tüm metinler bunu zorladı. dict Python 2'de bu tutarlılığı kırdı:

>>> foo(**{('a', 'b'): None})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() keywords must be strings
>>> dict(**{('a', 'b'): None})
{('a', 'b'): None}

Bu tutarsızlık Python (Pypy, Jython, IronPython) 'un diğer uygulamalarına göre kötüydü. Bu nedenle Python 3'te bu kullanım bir kırılma değişikliği olabileceği için düzeltildi.

Size, yalnızca bir dilin bir sürümünde çalışan veya yalnızca belirli keyfi kısıtlamalarla çalışan kodları kasten yazmanın kötü niyetli olmadığını bildiririm.

Başka bir yorum:

dict(x.items() + y.items()) Python 2 için hala en okunaklı çözümdür. Okunabilirlik sayılır.

Benim cevabım: merge_two_dicts(x, y) Aslında okunabilirlik konusunda endişeliysek, aslında bana daha açık görünüyor. Python 2 giderek daha fazla kullanımdan kaldırıldığı için ileriye dönük değildir.

Daha az performans ama doğru Ad-hocs

Bu yaklaşımlar daha az performanslıdır, ancak doğru davranışları sağlayacaktır. Olucaklar daha az daha performanslı copy ve update veya yeni ambalajdan çıkarma, çünkü her bir anahtar-değer çiftinden daha yüksek bir soyutlama seviyesinde yineliyorlar, ama onlar yap Öncelik sırasına saygı gösterme (sonuncusunun önceliği vardır)

Ayrıca, dikteleri bir dict anlama içinde elle de zincirleyebilirsiniz:

{k: v for d in dicts for k, v in d.items()} # iteritems in Python 2.7

ya da python 2.6'da (ve belki de jeneratör ifadeleri kullanıldığında 2.4'e kadar):

dict((k, v) for d in dicts for k, v in d.items())

itertools.chain Yineleyicileri, anahtar / değer çiftleri üzerinden doğru sıraya göre zincirler:

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

Performans analizi

Sadece doğru davranışları olduğu bilinen kullanımların performans analizini yapacağım.

import timeit

Ubuntu 14.04 üzerinde yapılır

Python 2.7'de (sistem Python):

>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.5726828575134277
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.163769006729126
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.iteritems(), y.iteritems()))))
1.1614501476287842
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
2.2345519065856934

Python 3.5'de (deadsnakes PPA):

>>> min(timeit.repeat(lambda: {**x, **y}))
0.4094954460160807
>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.7881555100320838
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.4525277839857154
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.items(), y.items()))))
2.3143140770262107
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
3.2069112799945287

Sözlüklerde Kaynaklar


3352
2017-11-10 22:11





Senin durumunda ne yapabilirsin:

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

Bu, istediğin gibi, son demeyi zve anahtarın değerini yap b ikinci tarafından uygun şekilde geçersiz kılınmalıdırydict değeri:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = dict(x.items() + y.items())
>>> z
{'a': 1, 'c': 11, 'b': 10}

Python 3'ü kullanırsanız, sadece biraz daha karmaşıktır. Yaratmak z:

>>> z = dict(list(x.items()) + list(y.items()))
>>> z
{'a': 1, 'c': 11, 'b': 10}

1440
2017-09-02 07:50





Bir alternatif:

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

547
2017-09-02 13:00



Bunun, sorunun sağladığı critera ile niçin uyuşmadığını açıklığa kavuşturmak için: bu tek bir ifade değildir ve z dönüşmez. - Alex
@Alex bazen asıl soru doğru soru değildir. Örneğin, düzenli bir ifadenin pythonic olmayan bir canavarını kullanmanız gerekiyorsa, örneğin, bir satırda veya iki şık çizgide bir şeyler yapmak için. X yapmak, sonra iki satırı kullanın. {**x, **y} kabul edilen cevapta yaklaşım bir canavarlıktır. - neuronet
@neuronet her oneliner genellikle farklı bir bileşene dönüşmesi gereken kodu hareket ettirir ve orada çözer. Bu kesinlikle davalardan biri. ama diğer diller bunun için python'dan daha güzel yapılara sahiptir. ve öğeyi döndüren referanslı şeffaf bir varyantın olması, bir şeylere sahip olmak güzel bir şeydir. - Alex
Bunu şu şekilde ifade edin: Eğer bir satır kodunuzu açıklayan insanlara iki satırlık yorum yazmanız gerekirse ... bunu gerçekten bir satırda yaptınız mı? :) Tamamen katılıyorum Python bunun için iyi değil: çok daha kolay bir yol olmalı. Bu cevap daha pythonik olsa da, gerçekten açık veya net olan tüm bunlar mı? Update insanların çok kullanma eğiliminde oldukları "çekirdek" işlevlerden biri değildir. - neuronet


Başka, daha özlü, seçenek:

z = dict(x, **y)

Not: Bu popüler bir cevap oldu, ancak şunu belirtmek önemlidir y herhangi bir dize olmayan anahtarlara sahiptir, bunun aslında bir CPython uygulama detayının kötüye kullanılması olduğu ve Python 3'te veya PyPy, IronPython veya Jython'da çalışmadığı gerçeği. Ayrıca, Guido hayranı değil. Bu yüzden ileriye dönük veya çapraz uygulama taşınabilir kodlar için bu tekniği tavsiye edemeyeceğim, ki bu gerçekten tamamen kaçınılması gerektiği anlamına geliyor.


273
2017-09-02 15:52





Bu muhtemelen popüler bir cevap olmayacak, ama kesinlikle bunu yapmak istemiyorsunuz. Bir kopyası olan bir kopyasını istiyorsanız, kopyayı kullanın (veya deepcopyne istediğinize bağlı olarak) ve ardından güncelleyin. İki kod satırı çok daha okunaklı - daha Pythonic - .items () + .items () ile tek satır oluşturulmasından daha fazladır. Açık, örtük olmaktan iyidir.

Ayrıca, .items () (Python 3.0 öncesi) kullandığınızda, dict öğesinden öğeleri içeren yeni bir liste oluşturuyorsunuz. Eğer sözlükleriniz büyükse, o zaman bu oldukça fazla bir yüktür (birleştirilmiş dict oluşturulduğu anda atılacak iki büyük liste). update () öğesi daha verimli çalışabilir, çünkü ikinci dict item-by-item üzerinden çalışabilir.

Açısından zaman:

>>> 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 ilk iki arasındaki küçük yavaşlama okunabilirlik için buna değer. Ayrıca, sözlük oluşturma için anahtar kelime argümanları sadece Python 2.3'e eklenmişken, copy () ve update () eski sürümlerde çalışacaktır.


168
2017-09-08 11:16





Bir takip cevabında, bu iki alternatifin göreli performansını sordunuz:

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

Makinemde, en azından (oldukça sıradan bir x86_64 çalışan Python 2.5.2), alternatif z2 sadece daha kısa ve daha basit değil, aynı zamanda önemli ölçüde daha hızlıdır. Bunu kullanarak kendiniz için doğrulayabilirsiniz. timeit Python ile birlikte gelen modül.

Örnek 1: kendileri için ardışık 20 tamsayı haritalayan özdeş sözlükler:

% 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 3.5 ya da öylesine bir faktörle kazanır. Farklı sözlükler oldukça farklı sonuçlar veriyor gibi görünüyor, ancak z2 her zaman önden çıkıyor gibi görünüyor. (Eğer tutarsız sonuçlar elde ederseniz aynı test et, geçmeyi dene -r varsayılan 3'ten daha büyük bir sayı ile)

Örnek 2: 252 kısa dizeyi tamsayılarla eşleştiren çakışmayan sözlükler ve tam tersi:

% 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 10'luk bir faktörle kazanıyor. Bu benim kitabımda oldukça büyük bir kazanım!

Bu ikisini karşılaştırdıktan sonra merak ettim z1'' zayıf performans '' '' '' '' '' '' '' '' '' '' '' '' '' öğesi, iki öğe listesini oluşturmanın ek yüküne atfedilebilirdi; bu da bu değişimin daha iyi çalışıp çalışmadığını merak etmeme neden oldu:

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

Birkaç hızlı test, ör.

% 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

sonuca varmamı sağla z3 biraz daha hızlı z1ama neredeyse en hızlı değil z2. Kesinlikle ekstra yazarak değmez.

Bu tartışmada hala önemli olan bir şey eksiktir. Bu iki alternatifin birleştirilmesiyle "alternatif" bir performans karşılaştırmasıdır. update yöntem. Her şeyi x veya y olarak değiştiren ifadeleriyle eşit bir zemin üzerinde tutmaya çalışmak için, aşağıdaki gibi yerinde değiştirmek yerine x'in bir kopyasını yapacağım:

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

Tipik bir sonuç:

% 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

Diğer bir deyişle, z0 ve z2 Esas olarak aynı performansa sahip gibi görünüyor. Bunun bir tesadüf olabileceğini düşünüyor musunuz? Yapmıyorum....

Aslında, saf Python kodunun bundan daha iyisini yapmasının imkansız olduğunu iddia etmek için gidebilirdim. Ve bir C uzatma modülünde önemli ölçüde daha iyi yapabiliyorsanız, Python üyelerinin kodunuzu (ya da yaklaşımınızda bir varyasyon) Python çekirdeğiyle birleştirmekle ilgilenebileceğini hayal ediyorum. Python kullanır dict bir çok yerde; operasyonlarını optimize etmek çok önemli.

Bunu da yazabilirsin

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

Tony'nin yaptığı gibi, ancak (şaşırtıcı bir şekilde değil), gösterimdeki fark, performans üzerinde ölçülebilir bir etki yaratmıyor. Hangisi size uygunsa onu kullanın. Elbette, iki deyim versiyonunun anlaşılması daha kolay olduğunu belirtmek kesinlikle doğru.


116
2017-10-23 02:38



Bu Python 3'te çalışmıyor; items() catenable değildir ve iteritems bulunmuyor. - Antti Haapala


Benzer bir şey istedim, ancak yinelenen anahtarlardaki değerlerin nasıl birleştirildiğini belirleme yeteneği sayesinde, bunu hackledim (ancak çok fazla test etmedim). Açıkçası bu tek bir ifade değil, tek bir işlev çağrısı.

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

86
2017-09-04 19:08





Python 3'te kullanabilirsiniz collections.ChainMap tek, güncellenebilir bir görünüm oluşturmak için birden çok dikte veya başka eşlemeyi birlikte gruplandırır:

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

73
2018-04-28 03:15



Ancak ChainMap'i kullanırken dikkatli olmanız gerekir ki, eğer bir çift anahtar varsa, ilk eşleştirmeden elde edilen değerler kullanılır. del Üzerine bir ChainMap c, bu anahtarın ilk eşleştirmesini siler. - Prerit
@Prerit Yapması için başka ne beklerdiniz? Zincirli isim alanlarının çalışması normal yoldur. Bash'ta $ PATH'nin nasıl çalıştığını düşünün. Yoldaki bir yürütülebilir dosyayı silmek, aynı adı taşıyan başka bir yürütülebilir dosyayı ön tarafa aktaramamaktadır. - Raymond Hettinger
@Raymond Hettinger Katılıyorum, sadece bir uyarı ekledi. Çoğu insan bunu bilmeyebilir. : D - Prerit
Sadeliği tavsiye etmek için buraya geldim collections.ChainMap. - hughdbrown
Aslında, burada sahip olduğunuz çıktı türünü kullanmadan bile elde edebilirsiniz. ChainMap sağ? Yani, tek yapman gereken sadece güncellemek z = {**x, **y} ve geleneksel adımları takip edin, işte bu! - Steffi Keran Rani J


Yinelemeli / derin bir dict güncellemek

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

gösteri:

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

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

print deepupdate(pluto_original, pluto_update)

Çıktılar:

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

Düzenlemeler için teşekkürler rednaw.


61
2017-11-29 11:52





Kopya kullanmadan düşünebildiğim en iyi versiyon şöyle olurdu:

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

Daha hızlı dict(x.items() + y.items()) ama kadar hızlı değil n = copy(a); n.update(b)En azından CPython'da. Bu sürüm ayrıca değiştirirseniz Python 3'te de çalışır iteritems() için items(), otomatik olarak 2to3 aracıyla yapılır.

Şahsen bu sürümü en çok beğendim çünkü tek bir işlevsel sözdiziminde ne istediğimi oldukça iyi anlatıyor. Tek küçük problem, y'den gelen değerlerin x'den gelen değerlere göre öncelikli olduğunu açıkça göstermemesidir, ancak bunu anlamak zor olduğuna inanmıyorum.


54
2017-10-14 18:55