Kaip sujungti du žodynus vienoje išraiška?

Turiu du „Python“ žodynus, ir noriu parašyti vieną išraišką, kuri grąžina šiuos du žodynus, susijungimą. update() metodas bus tas, ko man reikia, jei jis grąžins rezultatą ir nekeičia dikto.

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

Kaip galiu gauti šį galutinį kombinuotą diktuojamą z , o ne x ?

(Kad būtų aišku, tvarkymas prieštarauja naujausiems „ dict.update() naujausioms konfliktams. “

3587
02 сент. nustatė Carl Meyer 02 sept. 2008-09-02 10:44 '08 at 10:44 2008-09-02 10:44
@ 52 atsakymai
  • 1
  • 2

Kaip sujungti vieną Python žodyną vienoje išraiška?

Žodynams x ir y z tampa smulkiai kombinuotu žodynu, kurio reikšmės yra y pakeičiančios reikšmes iš x .

  • Python 3.5 arba naujesnėje versijoje:

     z = {**x, **y} 
  • „Python 2“ (arba 3.4 ar žemiau) rašykite funkciją:

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

    ir dabar:

     z = merge_two_dicts(x, y) 

paaiškinimas

Tarkime, jūs turite du diktatus, ir norite juos sujungti į naują, nekeičiant originalių:

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

Norimas rezultatas - gauti naują žodyną ( z ) su sujungtomis reikšmėmis, o antrosios dikto reikšmės perrašomos iš pirmųjų.

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

Nauja sintaksė, siūloma PEP 448 ir prieinama su Python 3.5 ,

 z = {**x, **y} 

Ir tai tikrai vienintelė išraiška.

Atkreipkite dėmesį, kad galime sujungti su raidėmis:

 z = {**x, 'foo': 1, 'bar': 2, **y} 

ir dabar:

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

Dabar jis parodo, kaip jis įgyvendinamas 3.5 versijos grafike, PEP 478 , ir dabar jis rodomas dokumente „ Kas naujo Python 3.5“ .

Tačiau, kadangi daugelis organizacijų vis dar naudoja „Python 2“, galite ją suderinti atgal. Klasikinis „Pythonic“ metodas, pasiekiamas „Python 2“ ir „Python 3.0-3.4“, yra tai padaryti kaip dviejų pakopų procesas:

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

Abiem būdais y bus antrasis, o jo vertės pakeis x reikšmes, todėl 'b' parodys 3 mūsų galutiniame rezultate.

Dar ne „Python 3.5“, bet noriu vienos išraiškos

Jei dar nesinaudojate „Python 3.5“ arba turite parašyti atgalinį suderinamą kodą ir norite, kad jis būtų vienoje išraiška, efektyviausias ir teisingiausias būdas yra įdėti jį į funkciją:

 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 

ir tada turite vieną išraišką:

 z = merge_two_dicts(x, y) 

Taip pat galite sukurti funkciją, kuri sujungtų neapibrėžtą diktatų skaičių nuo nulio iki labai didelio skaičiaus:

 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 

Ši funkcija veiks 2 ir 3 Python visuose diktatuose. pavyzdžiui, duomenys diktuoja nuo a iki g :

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

ir raktų vertės poros g bus viršesnės už parametrus nuo a iki f ir pan.

Kitų atsakymų kritika

Nenaudokite to, ką matote anksčiau priimtame atsakyme:

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

„Python 2“ atmintyje kiekvienam diktui sukuriate du sąrašus, sukuriate trečiąjį atmintyje esantį sąrašą, kurio ilgis lygus pirmųjų dviejų ilgių ilgiui, ir tada atmesti visus tris sąrašus, kad sukurtumėte diktą. „Python 3“ tai nepavyks, nes du dict_items kartu dict_items ne du sąrašus -

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

ir jūs turėsite juos aiškiai sukurti kaip sąrašus, pvz., z = dict(list(x.items()) + list(y.items())) . Tai yra išteklių ir kompiuterinės galios švaistymas.

Panašiai, derinant items() Python 3 („Python 2.7“ viewitems() , taip pat nepavyks, jei reikšmės yra objektai, kurių negalima keisti (pvz., Sąrašai). Net jei jūsų vertybės yra tinkamos, nes rinkiniai yra semantiniai, elgesys nėra apibrėžtas pagal prioritetą. Taigi nedarykite to:

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

Šis pavyzdys rodo, kas atsitinka, kai vertės nėra atskiriamos:

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

Čia pateikiamas pavyzdys, kur y turėtų būti pirmenybė, tačiau vietoj x pasirinktos eilės vertės išsaugoma vertė iš x:

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

Kitas įsilaužimas, kurį neturėtumėte naudoti:

 z = dict(x, **y) 

Jis naudoja dict konstruktorių ir labai greitai ir efektyviai naudoja atmintį (netgi šiek tiek daugiau nei mūsų dviejų pakopų procesas), bet jei tiksliai nežinote, kas čia vyksta (tai yra, antrasis diktas perduodamas kaip argumentas dikto konstruktoriaus raktiniams žodžiams) sunku skaityti, jis nėra skirtas naudoti, todėl jis nėra „Pythonic“.

Čia yra pavyzdys, kaip naudoti django .

Skaičiai yra skirti maišymo klavišams gauti (pvz., Frozensets arba tuples), tačiau šis metodas neveikia Python 3, kai raktai nėra stygos.

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

sąrašo kalbos rašytojas Guido van Rossum rašė:

Sutinku su diktavimo ({}, ** {1: 3}) neteisėta deklaracija, nes galiausiai tai yra piktnaudžiavimas ** mechanizmu.

ir taip pat

Matyt, diktas (x, ** y) naudojamas kaip „kietas įsilaužimas“ į „skambinti x.update (y) ir grįžti x“. Asmeniškai manau, kad tai yra labiau niekinga nei vėsioje.

Mano supratimas (kaip ir kalbos kūrėjo supratimas), kad numatomas dikto dict(**y) skirtas tam, kad būtų sukurtos skaitymo tikslai, pavyzdžiui:

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

vietoj

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

Atsakyti į komentarus

Nepaisant to, ką Guido sako, dict(x, **y) atitinka dikto specifikaciją, kuri, beje, yra. veikia tiek „Python 2“, tiek „3.“. Tai, kad tai veikia tik eilutės raktus, yra tiesioginis raktinių žodžių parametrų veikimo rezultatas, o ne trumpas dikto naudojimas. Be to, operatoriaus ** naudojimas šioje vietoje nėra piktnaudžiavimas mechanizmu, iš tikrųjų ** jis buvo sukurtas specialiai žodžiams perduoti kaip raktiniai žodžiai.

Vėlgi, tai neveikia 3, kai raktai nėra stygos. Netiesioginė skambučių sutartis yra ta, kad reguliarūs diktatai užima vardų vietas, o vartotojai turi tik perduoti pagrindinius argumentus, kurie yra stygos. Visi kiti kariuomenės pajėgos privertė jį. dict nutraukė šią seką „Python 2“:

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

Šis neatitikimas buvo blogas, atsižvelgiant į kitus „Python“ diegimus (Pypy, Jython, IronPython). Taigi, tai buvo nustatyta Python 3, nes šis naudojimas gali būti svarbus pokytis.

Manau, kad tai yra kenkėjiškas nekompetentingumas - tyčia rašyti kodą, kuris veikia tik vienoje kalbos versijoje arba veikia tik pagal tam tikrus savavališkus apribojimus.

Daugiau komentarų:

dict(x.items() + y.items()) vis dar yra pats skaitomiausias sprendimas „Python 2“. Skaitymo klausimai.

Mano atsakymas: merge_two_dicts(x, y) iš tikrųjų man atrodo daug aiškesnis, jei tikrai susirūpiname skaitymu. Ir tai nėra suderinama su ateitimi, nes „Python 2“ tampa vis pasenusi.

{**x, **y} neatrodo, kad tvarkytų įdėtus žodynus. įdėtų raktų turinys paprasčiausiai perrašomas, nėra sujungtas [...]. Galų gale mane sudegino šie atsakymai, kurie nesusijungia rekursiškai, ir buvau nustebęs, kad niekas to nepaminėjo. Vertindamas žodį „sujungti“, šie atsakymai apibūdina „vieno diktato atnaujinimą“, o ne susijungimą.

Taip Turiu jums atsiųsti atgal į klausimą, kuriam reikalingas paviršinis dviejų žodynų sujungimas, o pirmoji vertė perrašoma antra - viena išraiška.

Darant prielaidą, kad yra du žodynai, galima rekursyviai juos sujungti į vieną funkciją, bet jūs turite būti atsargūs, kad nekeičiau krypčių iš bet kokio šaltinio, o patikimiausias būdas išvengti to yra padaryti kopiją, kai priskiriamos reikšmės. Kadangi raktai turi būti išnykę ir todėl paprastai nekintami, nėra prasmės juos kopijuoti:

 from copy import deepcopy def dict_of_dicts_merge(x, y): z = {} overlapping_keys = x.keys()  y.keys() for key in overlapping_keys: z[key] = dict_of_dicts_merge(x[key], y[key]) for key in x.keys() - overlapping_keys: z[key] = deepcopy(x[key]) for key in y.keys() - overlapping_keys: z[key] = deepcopy(y[key]) return z 

Naudoti:

 >>> x = {'a':{1:{}}, 'b': {2:{}}} >>> y = {'b':{10:{}}, 'c': {11:{}}} >>> dict_of_dicts_merge(x, y) {'b': {2: {}, 10: {}}, 'a': {1: {}}, 'c': {11: {}}} 

Neatidėliotinas sprendimas kitoms vertėms yra daug platesnis už šio klausimo taikymo sritį, todėl nurodysiu, kad atsakysiu į kanoninį klausimą „Žodynų žodynai“.

Mažiau produktyvūs, bet teisingi „Ad-hocs“

Šie metodai yra mažiau veiksmingi, tačiau jie užtikrins tinkamą elgesį. Jie bus daug mažiau produktyvūs nei copy ir update arba naujas išpakavimas, nes jie kartojasi per kiekvieną pagrindinės vertės porą aukštesniu abstrakcijos lygiu, tačiau jie laikosi prioritetų eilės (paskutiniai diktuojami pirmenybė)

Taip pat galite suprasti žodžius rankiniu būdu:

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

arba Python 2.6 (ir, galbūt, jau 2.4, kai buvo įvestos generatoriaus išraiškos):

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

itertools.chain iteratoriai raktų vertės porose teisinga tvarka:

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

Veiklos analizė

Aš analizuosiu tik tuos atvejus, kai žinoma, kad jie elgiasi teisingai.

 import timeit 

„Ubuntu“ 14.04

„Python 2.7“ („Python“ sistema):

 >>> 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“ („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 

Žodyno ištekliai

3869
11 нояб. Atsakymą pateikė Aaron Hall lapkričio 11 d. 2014-11-11 01:11 '14 at 11:11 am 2014-11-11 01:11

Jūsų atveju galite tai padaryti:

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

Tai, kaip norite, įterpkite galutinį diktuoklę į z ir teisingai pakeiskite b klavišo vertę su antrąja verte ( y ):

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

Jei naudojate „Python 3“, tai yra šiek tiek sudėtingesnis. Jei norite sukurti z :

 >>> z = dict(list(x.items()) + list(y.items())) >>> z {'a': 1, 'c': 11, 'b': 10} 
1490 m
02 сент. Atsakyti Thomas Vander Stichele 02 Sep 2008-09-02 10:50 '08 at 10:50 AM 2008-09-02 10:50

Alternatyva:

 z = x.copy() z.update(y) 
574
02 сент. Matthew Schinckel atsakymas 02 Sep 2008-09-02 16:00 '08 at 4:00 2008-09-02 4:00

Kitas glaustesnis variantas:

 z = dict(x, **y) 

Pastaba : Tai tapo populiariu atsakymu, tačiau svarbu pabrėžti, kad jei y turi bet kokių nespecifinių raktų, tai, kad jis veikia, yra piktnaudžiavimas CPython įgyvendinimo detalėmis, ir jis neveikia Python 3, PyPy, IronPython ar Jython. Be to, „ Guido“ nėra gerbėjas . Todėl negaliu rekomenduoti šio metodo nešiojamam kodui su pažangiu suderinamumu ar kryžminiu įgyvendinimu, o tai iš tikrųjų reiškia, kad jis turėtų būti visiškai pašalintas.

288
02 сент. Atsakymą pateikė Carl Meyer 02 Sep. 2008-09-02 18:52 '08 at 18:52 2008-09-02 18:52

Tai tikriausiai nebus populiarus atsakymas, bet jūs beveik nenorite to padaryti. Jei jums reikia sujungimo kopijos, naudokite kopiją (arba giluminę kopiją, priklausomai nuo to, ką norite), tada atnaujinkite. Dvi kodų eilutės yra daug skaitomos - daugiau „Pythonic“ - nei vienos eilutės sukūrimas naudojant .items () + .items (). Aiškus yra geriau nei numanomas.

Be to, kai naudojate .items () (prieš Python 3.0), sukuriate naują sąrašą, kuriame yra elementų iš dikto. Jei jūsų žodynai yra dideli, ten yra daug pridėtinių (du dideli sąrašai, kurie bus išmesti, kai tik bus sukurtas kombinuotas diktas). atnaujinimas () gali veikti efektyviau, nes jis gali veikti per antrąjį elementą dict-by-item.

Laiko atžvilgiu :

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

TJO yra mažas sulėtėjimas tarp pirmųjų dviejų, kurias verta skaityti. Be to, raktinių žodžių žodyno argumentai buvo įtraukti tik į „Python 2.3“, o kopijavimas () ir naujinimas () veiks senesnėse versijose.

178
08 сент. Atsakymą pateikė Tony Meyer. 2008-09-08 14:16 '08 at 14:16 pm 2008-09-08 14:16

Toliau pateiktame atsakyme paklausėte apie šių dviejų alternatyvų santykinį našumą:

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

Mano mašinoje bent jau (gana įprastas x86_64, dirbantis su Python 2.5.2), alternatyva z2 ne tik trumpesnė ir paprastesnė, bet ir daug greičiau. Jį galite išbandyti pats naudodamiesi „Python“ pateiktu timeit moduliu.

1 pavyzdys: identiški žodynai, rodantys 20 iš eilės sveikų skaičių:

 % 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 laimi 3,5 karto. Atrodo, kad skirtingi žodynai duoda visiškai skirtingus rezultatus, bet z2 visada atrodo išeinant į priekį. (Jei dėl to paties bandymo gaunami nenuoseklūs rezultatai, pabandykite perjungti į -r , kurio skaičius didesnis nei numatytasis.)

2 pavyzdys: nesuderinami žodynai, rodantys 252 trumpus eilutes sveikiesiems skaičiams ir atvirkščiai:

 % 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 laimi apie 10 kartų. Tai yra gana didelis laimėjimas mano knygoje!

Palyginus šiuos du, man įdomu, ar prastas „ z1 našumas gali būti susijęs su dviejų elementų sąrašų kūrimu, o tai savo ruožtu paskatino mane stebėtis, ar šis pakeitimas gali veikti geriau:

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

Pavyzdžiui, kai kurie greiti testai

 % 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 

paskatinti mane daryti išvadą, kad z3 šiek tiek greitesnis už z1 , bet ne taip greitai, kaip z2 . Tikrai ne verta visų papildomų tipų.

Šioje diskusijoje dar trūksta svarbių dalykų, kurie lygina šių alternatyvų efektyvumą su „akivaizdžiu“ dviejų sąrašų sujungimo būdu: naudojant update metodą. Jei norite pabandyti viską išlaikyti vienodomis sąlygomis su išraiškomis, nė viena iš jų nekeičia x ar y, ketinu padaryti x kopiją, o ne pakeisti ją vietoje taip:

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

Tipinis rezultatas:

 % 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 

Kitaip tariant, z0 ir z2 atrodo beveik tokie patys. Ar manote, kad tai gali būti atsitiktinumas? Aš ne ...

Tiesą sakant, norėčiau pasakyti, kad gryno „Python“ kodo neįmanoma padaryti kažką geriau nei tai padaryti. Ir jei jūs galite padaryti daug geriau C modulyje, manau, kad „Python“ žmonės gali būti suinteresuoti įtraukti jūsų kodą (ar jūsų požiūrio variantus) į „Python“ branduolį. „Python“ daugelyje vietų naudoja dict ; optimizuoti savo veiklą yra didelis dalykas.

Taip pat galite parašyti tai kaip

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

kaip Tony daro, bet (nenuostabu) skirtumas tarp žymėjimo neturi pastebimo poveikio našumui. Naudokite tai, kas jums tinka. Žinoma, jis visiškai teisus nurodydamas, kad versija su dviem pareiškimais yra daug lengviau suprantama.

123
23 окт. atsakymas, duotas spalio 22 d. 2008-10-23 05:38 '08 at 5:38 2008-10-23 05:38

Aš norėjau kažką panašaus, bet su galimybe nurodyti, kaip buvo sujungtos pagrindinės pagrindinės vertybės, todėl aš ją įsilaužiau (bet ne išbandžiau). Akivaizdu, kad tai nėra viena išraiška, bet tai yra vienas funkcijų skambutis.

 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 
91
04 сент. atsakymą pateikė rcreswick Sep 04 2008-09-04 22:08 '08 10:08 val. 2008-09-04 22:08

„Python 3“ galite naudoti „ collections.ChainMap“ , kuri sujungia kelis diktatus ar kitus žemėlapius, kad būtų sukurtas vienas atnaujinamas vaizdas:

 >>> 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 
82
28 апр. Raymond Hettinger atsakymas balandžio 28 d 2013-04-28 06:15 '13, 6:15, 2013-04-28 06:15

Rekursyvus / gilus atnaujinimas diktuoja

 def deepupdate(original, update): """ Recursively update a dict. Subdict 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 

Demonstravimas:

 pluto_original = { 'name': 'Pluto', 'details': { 'tail': True, 'color': 'orange' } } pluto_update = { 'name': 'Pluutoo', 'details': { 'color': 'blue' } } print deepupdate(pluto_original, pluto_update) 

Rezultatai:

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

Dėkojame, kad redagavote pakeitimus.

66
29 нояб. atsakymas pateikiamas Stan 29 lapkričio. 2011-11-29 14:52 '11 at 14:52 2011-11-29 14:52

Geriausia versija, kurią galėčiau galvoti nenaudojant kopijos, būtų:

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

Tai greičiau nei dict(x.items() + y.items()) , bet ne taip greitai, kaip n = copy(a); n.update(b) n = copy(a); n.update(b) bent jau CPython. Ši versija veikia ir „Python 3“, jei pakeisite iteritems() į items() , kurie automatiškai atliekami naudojant įrankį „2to3“.

Asmeniškai man patinka ši versija geriausiai, nes ji apibūdina gana gerą, kurią noriu vienoje funkcinėje sintaksėje. Vienintelė nedidelė problema yra ta, kad nėra aišku, jog y y vertybės yra viršesnės už x reikšmes, bet nemanau, kad tai sunku suprasti.

58
14 окт. atsakymas suteiktas 14 d. 2010-10-14 21:55 '10, 21:55, 2010-10-14 21:55
 x = {'a':1, 'b': 2} y = {'b':10, 'c': 11} z = dict(x.items() + y.items()) print z 

Elementams, turintiems raktus abiejuose žodynuose („b“), galite valdyti, kurie iš jų patenka į išvestį, įterpdami pastarąjį.

46
02 сент. Greg Hewgill atsakymas 02 Sep 2008-09-02 10:49 '08 at 10:49 2008-09-02 10:49

„Python 3.5“ (PEP 448) leidžia jums pasirinkti patogesnę sintaksę:

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

Arba netgi

 final = {'a': 1, 'b': 1, **x, **y} 
46
27 февр. atsakymą pateikė Bilal Syed Hussain 27 vasario mėn 2015-02-27 00:27 '15 prie 0:27 2015-02-27 00:27

Nors į šį klausimą jau buvo atsakyta kelis kartus, šis paprastas problemos sprendimas dar nenurodytas.

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

Tai taip pat greitai, kaip aukščiau paminėtas z0 ir blogis z2, bet lengva suprasti ir keisti.

39
14 окт. atsakymas pateikiamas fobie 14 okt. 2011-10-14 19:12 '11, 19:12, 2011-10-14 19:12
 def dict_merge(a, b): c = a.copy() c.update(b) return c new = dict_merge(old, extras) 

Tarp tokių šešėlių ir abejotinų atsakymų, šis ryškus pavyzdys yra vienintelis geras būdas sujungti diktofonus į Pythoną, kurį diktatorius patvirtino patys Guido van Rossum gyvenimui! Kažkas pasiūlė pusę šio, bet neįtraukė šios funkcijos.

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

suteikia:

 {'color': 'red', 'owner': 'Carl', 'model': 'Ferrari'} 
36
06 авг. Atsakymą pateikė Sam Watkins, rugpjūčio 06 d 2012-08-06 12:24 '12 12:24 val. 2012-08-06 12:24