─░ki s├Âzl├╝─č├╝ tek bir ifadede nas─▒l birle┼čtiririm?


Al─▒nan cevaba git


─░ki Python s├Âzl├╝─č├╝m var ve bu iki s├Âzl├╝─č├╝ d├Ând├╝ren tek bir ifade yazmak istiyorum. Bu update() y├Ântem, ihtiyac─▒m olan ┼čeydi, yerine bir dikte de─či┼čtirmek yerine sonucunu d├Ând├╝rd├╝yse.

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

Nas─▒l bu son birle┼čtirilmi┼č dict alabilirsiniz z , de─čil x ?

(Ekstra a├ž─▒k olmak gerekirse, sonuncusu, ├žat─▒┼čman─▒n ├╝stesinden gelen kazanc─▒ da dict.update() arad─▒─č─▒m ┼čeydir.)


4276









Cevap say─▒s─▒n─▒ say: 30






─░ki Python s├Âzl├╝─č├╝n├╝ tek bir ifadede nas─▒l birle┼čtirebilirim?

S├Âzl├╝klerde i├žin x ve y , z bir s─▒─č de─čerlerle S├Âzl├╝k birle┼čti olur y gelenler de─či┼čtirilmesi x .

  • Python 3.5 veya daha y├╝ksek s├╝r├╝mlerde:

     z = {**x, **y}
     
  • Python 2'de (veya 3.4 veya daha d├╝┼č├╝k) bir i┼člev yaz─▒n:

     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 ┼čimdi:

     z = merge_two_dicts(x, y)
     

a├ž─▒klama

Diyelim ki iki adet dize var ve orijinalleri de─či┼čtirmeden bunlar─▒ yeni bir dize birle┼čtirmek istiyorsunuz:

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

─░stenilen sonu├ž, z birle┼čtirilmi┼č de─čerlerle yeni bir s├Âzl├╝k ( ) elde etmek ve ikinci diktenin de─čerleri, ilk de─čerlerin ├╝zerine yaz─▒l─▒r.

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

PEP 448'de ├Ânerilen ve Python 3.5'ten itibaren temin edilebilecek yeni bir s├Âzdizimi ,

 z = {**x, **y}
 

Ve ger├žekten tek bir ifade.

Edebi g├Âsterimle de birle┼čebilece─čimize dikkat edin:

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

ve ┼čimdi:

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

┼×imdi 3.5 s├╝r├╝m├╝nde, PEP 478 s├╝r├╝m├╝nde uyguland─▒─č─▒ gibi g├Âsteriliyor ve ┼čimdi Python 3.5 belgesinde Yenilikler b├Âl├╝m├╝nde yerini ald─▒ .

Ancak, bir├žok kurum hala Python 2'de oldu─čundan, bunu geriye d├Ân├╝k olarak uyumlu bir ┼čekilde yapmak isteyebilirsiniz. Python 2 ve Python 3.0-3.4'te bulunan klasik Pythonic yolu, 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 da y ikinci olacak ve de─čerleri de─čerlerinin yerini alacak x , bu nedenle sonu├žta ortaya 'b' ├ž─▒kacak 3 .

Hen├╝z Python 3.5'te de─čil, tek bir ifade istiyorum

Hen├╝z Python 3.5'te de─čilseniz ya da geriye d├Ân├╝k uyumlu bir kod yazman─▒z gerekiyorsa ve bunu tek bir ifadede istiyorsan─▒z , en do─čru yakla┼č─▒m iken en iyi performans bir i┼člevi kullanmakt─▒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 s─▒f─▒rdan ├žok b├╝y├╝k bir say─▒ya kadar tan─▒ms─▒z say─▒da diski birle┼čtirmek i├žin bir i┼člev de yapabilirsiniz:

 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 fonksiyon t├╝m s├Âzl├╝kler i├žin Python 2 ve 3'te ├žal─▒┼čacakt─▒r. Verilen dicts ├Ârne─čin a i├žin g :

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

ve anahtar de─čer ├žiftleri g dicts g├Âre ├Âncelikli olaca─č─▒n─▒ a etmek f , vb.

Di─čer Cevaplar─▒n Ele┼čtirileri

Daha ├Ânce kabul edilen cevaplarda g├Ârd├╝─č├╝n├╝z├╝ kullanmay─▒n:

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

Python 2'de, her dikte i├žin bellekte iki liste olu┼čturursunuz, ilk ikisinin uzunlu─čuna e┼čit uzunlukta bellekte ├╝├ž├╝nc├╝ bir liste olu┼čturursunuz ve ard─▒ndan dikt olu┼čturmak i├žin ├╝├ž listeyi de at─▒yorsunuz. Python 3'te bu ba┼čar─▒s─▒z olur ├ž├╝nk├╝ dict_items iki listeyi iki listeye eklersiniz, iki listeyi 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 a├ž─▒k bir ┼čekilde bunlar─▒ listeler olarak olu┼čturman─▒z gerekecektir, ├Ârne─čin z = dict(list(x.items()) + list(y.items())) . Bu bir kaynak israf─▒ ve hesaplama g├╝c├╝d├╝r.

Benzer ┼čekilde, items() Python 3'teki ( viewitems() Python 2.7'deki) birle┼čimini almak, de─čerler payla┼č─▒lamayan nesneler oldu─čunda (├Ârne─čin, listeler gibi) ba┼čar─▒s─▒z olur. De─čerleriniz de─či┼čken olsa bile, k├╝meler anlamsal olarak s─▒ralanmad─▒─č─▒ndan, davran─▒┼č ├Ânceli─či a├ž─▒s─▒ndan tan─▒ms─▒zd─▒r. Yani bunu yapma:

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

Bu ├Ârnek, de─čerler anla┼č─▒lmaz oldu─čunda ne olaca─č─▒n─▒ 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 y'nin ├Ânceli─či olmas─▒ gereken bir ├Ârnek, ancak bunun yerine, k├╝melerin keyfi s─▒ralamas─▒ nedeniyle x'in de─čeri korunuyor:

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

Kullanmaman─▒z gereken bir ba┼čka hack:

 z = dict(x, **y)
 

Bu, yap─▒c─▒y─▒ kullan─▒r dict ve ├žok h─▒zl─▒ ve haf─▒zada verimlidir (iki a┼čamal─▒ s├╝recimizden biraz daha fazla) ancak burada tam olarak ne oldu─čunu tam olarak bilmiyorsan─▒z (yani, ikinci dikt, dikteye anahtar s├Âzc├╝k arg├╝manlar─▒ olarak ge├žirilir). Yap─▒c─▒), okunmas─▒ zor, ama├žlanan kullan─▒m de─čil ve bu y├╝zden Pythonic de─čil.

─░┼čte django'da d├╝zeltilen kullan─▒m─▒n bir ├Ârne─či .

Kesiklerin anahtar ta┼č─▒malar─▒ (├Ârne─čin frozensetler veya tuplesler) almalar─▒ ama├žlanm─▒┼čt─▒r, ancak bu y├Ântem Python 3'te, tu┼č dizeleri olmad─▒─č─▒nda 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
 

G├Ânderen posta listesine , Guido van Rossum, dilin yarat─▒c─▒s─▒ yazd─▒:

Sonu├žta ** mekanizmas─▒n─▒ k├Ât├╝ye kulland─▒─č─▒ i├žin dict ({}, ** {1: 3}) yasad─▒┼č─▒ ilan etme konusunda iyiyim.

ve

G├Âr├╝n├╝┼če g├Âre dikt (x, ** y), "x.update (y) ├ža─čr─▒s─▒ ve x" ifadesi i├žin "cool hack" olarak dola┼č─▒yor. ┼×ahsen ben cooldan daha a┼ča─č─▒l─▒k buluyorum.

Anlad─▒─č─▒m kadar─▒yla ( dilin yarat─▒c─▒s─▒n─▒n anlay─▒┼č─▒ da ) ama├žlanan kullan─▒m─▒n dict(**y) okunabilirlik amac─▒yla kodlar olu┼čturmak oldu─čud─▒r, ├Ârne─čin:

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

yerine

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

Yorumlara cevap

Guido'n─▒n s├Âylediklerine ra─čmen dict(x, **y) , btw olan dict spesifikasyonuna uygun. Python 2 ve 3'├╝n her ikisinde de ├žal─▒┼č─▒r. Bunun yaln─▒zca karakter dizileri i├žin i┼če yaramas─▒, anahtar kelime parametrelerinin nas─▒l ├žal─▒┼čt─▒─č─▒n─▒n do─črudan bir sonucudur; Buradaki ** i┼člecini de kullanm─▒yorsan─▒z, mekanizman─▒n k├Ât├╝ye kullan─▒lmas─▒, ger├žekte ** tam olarak anahtar kelimeleri anahtar kelimeler olarak iletmek i├žin tasarlanm─▒┼čt─▒.

Yine, tu┼člar karakter dizisi olmad─▒─č─▒nda 3 i├žin ├žal─▒┼čmaz. ├ľrt├╝k ├ža─čr─▒ s├Âzle┼čmesi, ad alanlar─▒n─▒n normal kurallar almas─▒d─▒r, oysa, kullan─▒c─▒lar yaln─▒zca dizge olan anahtar s├Âzc├╝k ba─č─▒ms─▒z de─či┼čkenlerini ge├žmelidir. Di─čer t├╝m ├ža─čr─▒labilirler onu zorlad─▒. dict Python 2'de bu tutarl─▒l─▒─č─▒ bozdu:

 >>> 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'un (Pypy, Jython, IronPython) di─čer uygulamalar─▒ dikkate al─▒nd─▒─č─▒nda k├Ât├╝yd├╝. B├Âylece Python 3'te sabitlendi, ├ž├╝nk├╝ bu kullan─▒m bir de─či┼čiklik olabilir.

Size yaln─▒zca bir dilin yaln─▒zca bir s├╝r├╝m├╝nde ├žal─▒┼čan veya yaln─▒zca belirli keyfi k─▒s─▒tlamalar verilen ┼čekilde ├žal─▒┼čan kod yazman─▒n kas─▒tl─▒ olarak kod yazmas─▒n─▒n k├Ât├╝ oldu─čunu belirtiyorum.

Di─čer yorumlar:

dict(x.items() + y.items()) Python 2 i├žin hala en okunakl─▒ ├ž├Âz├╝md├╝r. Okunabilirlik ├Ânemlidir.

Cevab─▒m: merge_two_dicts(x, y) Okunabilirlik konusunda ger├žekten endi┼čeliyiz, asl─▒nda bana ├žok daha net g├Âr├╝n├╝yor. Ve Python 2 giderek daha az kullan─▒ld─▒─č─▒ndan, ileriye d├Ân├╝k olarak uyumlu de─čildir.

{**x, **y} i├ž i├že s├Âzl├╝kleri ele g├Âr├╝nm├╝yor. i├ž i├že anahtarlar─▒n i├žeri─či basit├že ├╝zerine yaz─▒l─▒r, birle┼čtirilmez [...] ├ľzyinelemeyle birle┼čmeyen bu cevaplar taraf─▒ndan yak─▒ld─▒m ve hi├ž kimseden bahsetmedi─čime ┼ča┼č─▒rd─▒m. "Birle┼čtirme" kelimesini yorumlamamda, bu cevaplar "bir dikteyi di─čeriyle g├╝ncelleme" yi tan─▒mlamaktad─▒r, birle┼čmeyi de─čil.

Evet. Sizi iki s├Âzl├╝kten s─▒─č bir ┼čekilde bir araya gelmek isteyen soruna geri d├Ânmeliyim , ilk de─čerleri ikinci olan─▒n ├╝zerine yaz─▒l─▒r - tek bir ifadeyle.

─░ki s├Âzl├╝k s├Âzl├╝─č├╝ varsayal─▒m, bunlar─▒ tek tek bir i┼člevde yinelemeli olarak birle┼čtirebilirsiniz, ancak bu de─čerlerden birini atamad─▒─č─▒n─▒zdan emin olman─▒z gerekir; Anahtarlar─▒n y─▒kanabilir olmas─▒ ve genellikle de─či┼čmez olmas─▒ gerekti─činden, bunlar─▒ kopyalamak anlams─▒zd─▒r:

 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
 

Kullan─▒m─▒:

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

Di─čer de─čer t├╝rleri i├žin olas─▒l─▒klarla gelmek bu sorunun kapsam─▒ d─▒┼č─▒ndad─▒r, bu y├╝zden sizi bir "s├Âzl├╝k s├Âzl├╝kleri birle┼čtirme" konulu kanonik soruya cevab─▒m─▒ i┼čaret edece─čim .

Daha Az Performansl─▒ Ama Do─čru Reklamlar

Bu yakla┼č─▒mlar daha az performans g├Âsterir, ancak do─čru davran─▒┼č sa─člayacakt─▒r. Bunlar olacak daha az ├Âl├ž├╝lebilir daha copy ve update yeni a├žma bunlar soyutlama daha y├╝ksek bir seviyede her bir anahtar de─čeri ├žifti boyunca yineleme i├žin ya da, ancak bunu ├Âncelik s─▒ras─▒n─▒ (ikinci dicts ├Ânceli─če sahip) sayg─▒

Ayr─▒ca, bir el ile bir el yaz─▒s─▒ elde edip edinebilirsiniz:

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

veya python 2.6'da (ve belki de jenerat├Âr ifadeleri kullan─▒ld─▒─č─▒nda 2.4 kadar erken):

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

itertools.chain yineleyicileri anahtar / de─čer ├žiftleri ├╝zerinden do─čru s─▒rada zincirleyecektir:

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

Performans analizi

Sadece do─čru davrand─▒─č─▒ bilinen kullan─▒mlar─▒n performans analizini yapaca─č─▒m.

 import timeit
 

A┼ča─č─▒dakiler Ubuntu 14.04 tarihinde 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'te (deasnakes 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├╝klerle ─░lgili Kaynaklar


4931







Senin durumunda ne yapabilirsin:

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

Bu, istedi─činiz gibi, son dize girecek z ve anahtar─▒n de─čerini b , second ( y ) diktinin de─čerine g├Âre ge├žersiz k─▒l─▒nmas─▒n─▒ sa─člayacakt─▒r :

 >>> 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─▒yorsan─▒z, sadece biraz daha karma┼č─▒kt─▒r. Olu┼čturmak i├žin z :

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

1554







Bir alternatif:

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

605







Ba┼čka, daha ├Âzl├╝ bir se├ženek:

 z = dict(x, **y)
 

Not : Bu pop├╝ler bir cevap haline gelmi┼čtir, ancak y herhangi bir dize olmayan anahtar varsa, bunun ger├žekten i┼če yarad─▒─č─▒ ger├že─činin bir CPython uygulama detay─▒n─▒ k├Ât├╝ye kulland─▒─č─▒n─▒ ve Python 3'te ├žal─▒┼čmad─▒─č─▒n─▒ belirtmek ├Ânemlidir. veya PyPy, IronPython veya Jython'da. Ayr─▒ca, Guido hayran─▒ de─čil . Bu y├╝zden ileriye d├Ân├╝k veya ├žapraz uygulamal─▒ ta┼č─▒nabilir kod i├žin bu tekni─či tavsiye edemiyorum, bu ger├žekten tamamen ka├ž─▒n─▒lmas─▒ gerekti─či anlam─▒na gelir.


318







Bu muhtemelen pop├╝ler bir cevap olmayacak, ancak neredeyse kesinlikle bunu yapmak istemiyorsunuz. Bir birle┼čtirme olan bir kopya istiyorsan─▒z, o zaman kopya (veya ne istedi─činizi ba─čl─▒ olarak deepcopy ) kullan─▒n ve sonra g├╝ncelleyin. ─░ki kod sat─▒r─▒ daha okunakl─▒d─▒r - daha fazla Pythonic - .items () + .items () i├žeren tek sat─▒r olu┼čturma i┼čleminden. A├ž─▒k, ├Ârt├╝k olmaktan iyidir.

Ayr─▒ca, .items () (Python 3.0 ├Âncesi) kulland─▒─č─▒n─▒zda, dict ├Â─čelerini i├žeren yeni bir liste olu┼čturursunuz. E─čer s├Âzl├╝kleriniz ├žok b├╝y├╝kse, o zaman bu ├žok fazla ek y├╝k demektir (birle┼čtirilmi┼č dict olu┼čturulduktan hemen sonra at─▒lacak iki b├╝y├╝k liste). update () daha verimli ├žal─▒┼čabilir ├ž├╝nk├╝ ikinci dict ├Â─čeye g├Âre ilerleyebilir.

Zaman a├ž─▒s─▒ndan :

 >>> 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 ikisi aras─▒ndaki ufak yava┼člama okunabilirlik i├žin buna de─čer. Ek olarak, s├Âzl├╝k olu┼čturma i├žin anahtar kelime arg├╝manlar─▒ yaln─▒zca Python 2.3'te eklenmi┼č, ancak copy () ve update () daha eski s├╝r├╝mlerde ├žal─▒┼čacakt─▒r.


196







Bir sonraki cevapta, bu iki alternatifin g├Âreceli performans─▒ hakk─▒nda sorular sordunuz:

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

Makinemde, en az─▒ndan (Python 2.5.2 ├žal─▒┼čt─▒ran olduk├ža s─▒radan bir x86_64), alternatif z2 yaln─▒zca k─▒sa ve basit de─čil, ayn─▒ zamanda ├Ânemli ├Âl├ž├╝de daha h─▒zl─▒. timeit Python ile birlikte gelen mod├╝l├╝ kullanarak bunu kendiniz do─črulayabilirsiniz .

├ľrnek 1: arka arkaya 20 tam say─▒y─▒ e┼čleyen ayn─▒ 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 z2 veriyor gibi g├Âr├╝n├╝yor , ancak her zaman ├Âne ├ž─▒k─▒yor gibi g├Âr├╝n├╝yor. ( Ayn─▒ test i├žin tutars─▒z sonu├žlar elde ederseniz -r , varsay─▒lan 3'ten daha b├╝y├╝k bir say─▒ girmeyi deneyin .)

├ľrnek 2: 252 k─▒sa dizgiyi tam say─▒lara e┼čleyen ├╝st ├╝ste binmeyen s├Âzl├╝kler:

 % 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├ž!

Bu ikisini kar┼č─▒la┼čt─▒rd─▒ktan sonra, z1 d├╝┼č├╝k performans─▒n iki ├Â─če listesini olu┼čturman─▒n ek y├╝k├╝ne atfedilip y├╝klenemeyece─čini merak ettim , bu da bu de─či┼čimin daha iyi ├žal─▒┼č─▒p ├žal─▒┼čmayaca─č─▒n─▒ merak etmemi sa─člad─▒:

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

Birka├ž h─▒zl─▒ test, ├Ârne─čin

 % 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
 

beni, z3 bundan biraz daha h─▒zl─▒ z1 , ama neredeyse kadar h─▒zl─▒ olmayan bir sonu├ž ├ž─▒karmam i├žin y├Ânlendir z2 . Kesinlikle t├╝m ekstra yazmaya de─čmez.

Bu tart─▒┼čmada hala ├Ânemli olan bir ┼čey eksik; bu alternatiflerin iki listeyi birle┼čtirmenin "a├ž─▒k" yolu ile performans kar┼č─▒la┼čt─▒rmas─▒: update y├Ântemi kullanmak . Hi├žbir ┼čeyi x veya y'yi de─či┼čtirmeyen ifadelerle e┼čit d├╝zeyde tutmaya ├žal─▒┼čmak i├žin, yerinde de─či┼čtirmek yerine x'in bir kopyas─▒n─▒ olu┼čturaca─č─▒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
 

Ba┼čka bir deyi┼čle, z0 ve z2 esasen ayn─▒ performansa sahip g├Âr├╝nmektedir. 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 edecek kadar ileri giderdim. Ve bir C eklenti mod├╝l├╝nde ├Ânemli ├Âl├ž├╝de daha iyisini yapabiliyorsan─▒z, Python milletinin kodunuzu (veya yakla┼č─▒m─▒n─▒zdaki bir varyasyonun) Python ├žekirde─čine dahil etmekle ilgilenebilece─čini d├╝┼č├╝n├╝yorum. Python dict bir├žok yerde kullan─▒r ; operasyonlar─▒n─▒ optimize etmek ├žok ├Ânemli.

Bunu ayr─▒ca olarak da yazabilirsiniz.

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

Tony'nin yapt─▒─č─▒ gibi, ancak (┼ča┼č─▒rt─▒c─▒ olmayan bir ┼čekilde) g├Âsterimdeki fark, performans ├╝zerinde ├Âl├ž├╝lebilir bir etkiye sahip olmad─▒─č─▒ ortaya ├ž─▒k─▒yor. Hangisi size do─čru bakarsa kullan─▒n. Elbette, iki ifadeli s├╝r├╝m├╝n anla┼č─▒lmas─▒n─▒n daha kolay oldu─čunu belirtmekte kesinlikle hakl─▒.


136







Benzer bir ┼čey istedim ama yinelenen anahtarlardaki de─čerlerin nas─▒l birle┼čtirildi─čini belirleyebildi─čim i├žin, bunu hackledim (ama yo─čun bir ┼čekilde test etmedim). A├ž─▒k├žas─▒, bu tek bir ifade de─čil, ancak tek bir i┼člev ├ža─čr─▒s─▒d─▒r.

 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
 

102







Python 3.0 ve sonraki s├╝r├╝mlerinde , collections.ChainMap'i kullanarak, tek bir g├╝ncelle┼čtirilebilir g├Âr├╝n├╝m olu┼čturmak i├žin birden ├žok dikte veya di─čer e┼člemeleri birlikte gruplayan:

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

Python 3.5 ve sonraki s├╝r├╝mleri i├žin g├╝ncelleme : PEP 448 geni┼čletilmi┼č s├Âzl├╝k paketini a├žma ve a├žma i┼člemlerini kullanabilirsiniz . Bu h─▒zl─▒ ve kolayd─▒r:

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

100







Bir ├Âzyinelemeli / derin g├╝ncelleme

 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.


78


2011-11-29





Kopyay─▒ kullanmazken d├╝┼č├╝nebilece─čim en iyi s├╝r├╝m:

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

Daha h─▒zl─▒ daha var dict(x.items() + y.items()) ama kadar h─▒zl─▒ n = copy(a); n.update(b) , en az─▒ndan CPython ├╝zerinde. E─čer de─či┼čtirirseniz Bu s├╝r├╝m ayr─▒ca Python 3 ├žal─▒┼č─▒r iteritems() i├žin items() otomatik 2to3 arac─▒ taraf─▒ndan yap─▒l─▒r, hangi.

┼×ahsen bu s├╝r├╝m├╝ en ├žok seviyorum ├ž├╝nk├╝ tek bir i┼člevsel s├Âzdiziminde ne istedi─čimi olduk├ža iyi a├ž─▒kl─▒yor. Tek k├╝├ž├╝k sorun, y'den gelen de─čerlerin x'den gelen de─čerlere g├Âre ├Âncelikli oldu─čunu a├ž─▒k├ža belli etmemesidir, ancak bunu anlaman─▒n zor oldu─čuna inanm─▒yorum.


64







Python 3.5 (PEP 448) daha g├╝zel bir s├Âzdizimi se├žene─či sunar:

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

Ya da

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

55







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

Her iki s├Âzl├╝kteki ('b') tu┼člar─▒ olan ├Â─čeler i├žin, hangisinin sonda oldu─čunu belirterek ├ž─▒kt─▒da bitece─čini kontrol edebilirsiniz.


54







Soru zaten birka├ž kez cevaplanm─▒┼č olsa da, soruna bu basit ├ž├Âz├╝m hen├╝z listelenmemi┼čtir.

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

Yukar─▒da z0 ve yukar─▒da z2 oldu─ču kadar h─▒zl─▒d─▒r, fakat anla┼č─▒lmas─▒ ve de─či┼čtirilmesi kolayd─▒r.


44







 def dict_merge(a, b):
  c = a.copy()
  c.update(b)
  return c

new = dict_merge(old, extras)
 

Bu g├Âlgeli ve ┼č├╝pheli cevaplar aras─▒nda, bu parlak ├Ârnek, ya┼čam Guido van Rossum'un ya┼čam diktat├Âr├╝ taraf─▒ndan onaylanan Python'daki dikmeleri birle┼čtirmenin tek ve tek iyi yoludur ! Ba┼čka biri bunun yar─▒s─▒n─▒ ├Ânerdi, ancak bir i┼čleve koymad─▒.

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

verir:

 {'color': 'red', 'owner': 'Carl', 'model': 'Ferrari'}
 

42







E─čer lambdalar─▒n k├Ât├╝ oldu─čunu d├╝┼č├╝n├╝yorsan─▒z, daha fazla okumaya gerek yok. ─░stedi─činiz gibi h─▒zl─▒ ve haf─▒za a├ž─▒s─▒ndan verimli ├ž├Âz├╝m├╝ tek bir ifadeyle yazabilirsiniz:

 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}
 

Yukar─▒da ├Ânerildi─či gibi, iki sat─▒r kullanmak veya bir i┼člev yazmak muhtemelen daha iyi bir yoldur.


34


2011-11-23





Pitonik ol. Bir anlama kullan─▒n :

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

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

29







Python3'te, items y├Ântem art─▒k bir liste de─čil , k├╝me i┼člevi g├Âren bir g├Âr├╝n├╝m d├Ând├╝r├╝r . Bu durumda, birle┼čtirme i┼člemini yapman─▒z gerekir, ├ž├╝nk├╝ bir araya gelmek + i┼če yaramaz:

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

2.7 s├╝r├╝m├╝ndeki python3 benzeri davran─▒┼č i├žin, viewitems y├Ântem bunun yerine ├žal─▒┼čmal─▒d─▒r items :

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

Yine de bu g├Âsterimi tercih ediyorum, ├ž├╝nk├╝ onu birle┼čtirme yerine (unvan─▒n g├Âsterdi─či gibi) belli bir sendika operasyonu olarak d├╝┼č├╝nmek daha do─čal g├Âr├╝n├╝yor.

D├╝zenle:

Python 3 i├žin birka├ž puan daha. ─░lk dict(x, **y) olarak, tu┼člar y karakter dizisi olmad─▒k├ža hile python 3'te ├žal─▒┼čmayacak .

Ayr─▒ca, Raymond Hettinger en Chainmap cevab─▒ o arg├╝manlar─▒ olarak dicts iste─če ba─čl─▒ say─▒da alabilir, ancak bu yana, olduk├ža ┼č─▒k dok├╝manlardan s─▒ral─▒ olarak ger├žekle┼čtirilen her arama i├žin t├╝m dicts listesi bakar gibi g├Âr├╝n├╝r:

Aramalar, bir anahtar bulunana kadar altta yatan e┼člemeleri art arda arar.

Uygulaman─▒zda ├žok fazla arama varsa, sizi yava┼člatabilir:

 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
 

Yani aramalar i├žin daha yava┼č bir b├╝y├╝kl├╝k s─▒ras─▒ hakk─▒nda. Ben Chainmap hayran─▒y─▒m, ancak bir├žok arama olabilece─či yerlerde daha az pratik g├Âr├╝n├╝yor.


27







K├Ât├╝ye kullanma, MatthewÔÇÖun cevab─▒ i├žin tek ifadeli bir ├ž├Âz├╝me yol a├ž─▒yor :

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

Bir ifade istedi─čini s├Âylemi┼čtin, ben de lambda bir ismi ba─člamak i├žin suistimal ettim ve lambda'n─▒n tek ifade s─▒n─▒r─▒n─▒ a┼čmak i├žin tuples. S─▒k─▒┼čmaktan ├žekinmeyin.

Bunu kopyalamay─▒ umursam─▒yorsan─▒z, elbette bunu da yapabilirsiniz:

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

21







D├╝zeni koruyan itertools kullanan basit bir ├ž├Âz├╝m (son s├Âzler ├Âncelik ta┼č─▒r)

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

Ve kullan─▒m─▒:

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

20







─░ki s├Âzl├╝k

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

n s├Âzl├╝kler

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

sum K├Ât├╝ bir performansa sahip. Bkz https://mathieularose.com/how-not-to-flatten-a-list- of-lists-in-python/


20







Cevaplar bu s─▒─č s├Âzl├╝k i├žin iyi olsa da, burada tan─▒mlanan y├Ântemlerden hi├žbiri ger├žekten derin bir s├Âzl├╝k birle┼čimi yapmaz.

├ľrnekler takip:

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

Ki┼či b├Âyle bir ┼čeyin sonucunu bekler:

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

Bunun yerine, ┼čunu anl─▒yoruz:

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

'One' giri┼či, ger├žekten bir birle┼čme olsayd─▒, s├Âzl├╝─č├╝n├╝n i├žindeki ├Â─čeler olarak 'depth_2' ve 'extra' olmal─▒d─▒r.

Ayn─▒ zamanda zinciri kullanmak da i┼če yaramaz:

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

Sonu├žlar:

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

Rcwesick'in verdi─či derin birle┼čme de ayn─▒ sonucu veriyor.

Evet, ├Ârnek s├Âzl├╝kleri birle┼čtirmek i├žin i┼če yarayacak, ancak hi├žbiri birle┼čtirme i├žin genel bir mekanizma de─čil. Ger├žek bir birle┼čtirme yapan bir y├Ântem yazd─▒─č─▒mda bunu daha sonra g├╝ncelleyece─čim.


15







Buradaki ve ba┼čka yerlerdeki fikirleri ├žizerek bir i┼člevi anlad─▒m:

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

Kullan─▒m (python 3'te test edilmi┼čtir):

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

Bunun yerine bir lambda kullanabilirsiniz.


10







Bug├╝ne kadar listelenen ├ž├Âz├╝mlerde ya┼čad─▒─č─▒m sorun, birle┼čtirilmi┼č s├Âzl├╝─č├╝n "b" anahtar─▒n─▒n de─čerinin 10 olmas─▒, ancak benim d├╝┼č├╝nceme g├Âre, 12 olmas─▒ gerekti─čidir. Bu ba─člamda, a┼ča─č─▒dakileri sunuyorum:

 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
 

Sonu├žlar:

 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







 from collections import Counter
dict1 = {'a':1, 'b': 2}
dict2 = {'b':10, 'c': 11}
result = dict(Counter(dict1) + Counter(dict2))
 

Bu probleminizi ├ž├Âzmeli.


10







Bu tek bir dilbilgisi anlay─▒┼č─▒yla yap─▒labilir:

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

Benim g├Âr├╝┼č├╝me g├Âre, 'tek ifade' k─▒sm─▒ i├žin en iyi cevap, fazladan bir fonksiyona ihtiya├ž duymad─▒─č─▒ndan k─▒sa.


9







(Yaln─▒zca Python2.7 * i├žin; Python3 * i├žin daha basit ├ž├Âz├╝mler vard─▒r.)

Standart bir k├╝t├╝phane mod├╝l├╝n├╝ i├že aktarmaktan ├žekinmiyorsan─▒z,

 from functools import reduce

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

(─░├žindeki or a bit lambda gereklidir, ├ž├╝nk├╝ dict.update her zaman None ba┼čar─▒ya d├Âner .)


9


2016-03-28





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







.update Hi├žbir ┼čey d├Ând├╝rmeyen aptalca .
Sorunu ├ž├Âzmek i├žin sadece basit bir yard─▒mc─▒ i┼člev kullan─▒yorum:

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

├ľrnekler:

 merge(dict1,dict2)
merge(dict1,dict2,dict3)
merge(dict1,dict2,dict3,dict4)
merge({},dict1,dict2)  # this one returns a new copy
 

7







Mutasyona izin vermezseniz x ,

 x.update(y) or x
 

Basit, okunabilir, performans. Sen biliyor update() hep d├Âner None yanl─▒┼č bir de─čer olan. Bu y├╝zden her zaman de─čerlendirecek x .

Standart k├╝t├╝phanede mutasyona u─čram─▒┼č y├Ântemler, konvansiyonel olarak update geri d├Ân├╝┼č gibi , None bu hile de bunun ├╝zerinde ├žal─▒┼čacak.

Bu kurallara uymayan bir kitapl─▒k kullan─▒yorsan─▒z, bir tuple ekran─▒n─▒ ve dizinini, yerine tek bir ifade yapmak i├žin kullanabilirsiniz or , ancak okunabilir de─čildir.

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

x Hen├╝z bir de─či┼čkene sahip de─čilseniz, lambda bir atama ifadesi kullanmadan yerel yapmak i├žin kullanabilirsiniz . Bu , i┼člevsel dillerde ortak bir teknik olan letece bir ifade lambda olarak kullan─▒lmas─▒na , ancak unpythonic'e ba─čl─▒d─▒r.

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

Bir kopya istiyorsan─▒z, PEP 448 en iyisidir {**x, **y} . Ancak bu m├╝mk├╝n de─čilse, burada da ├žal─▒┼čal─▒m .

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

6







Bunun, sorular─▒n ├Âzelliklerine tam olarak uymad─▒─č─▒n─▒ biliyorum ("bir liner"), ancak yukar─▒daki yan─▒tlar─▒n hi├žbiri bu y├Âne girmedi─či i├žin performans sorununa ├žok fazla ve ├žok say─▒da cevap geldi, d├╝┼č├╝ncelerime katk─▒da bulunmam gerekti─čini hissettim.

Kullan─▒m durumuna ba─čl─▒ olarak, verilen girdi s├Âzl├╝klerinden "ger├žek" birle┼čtirilmi┼č bir s├Âzl├╝k olu┼čturmak gerekli olmayabilir. Bunu yapan bir bak─▒┼č a├ž─▒s─▒ bir├žok durumda yeterli olabilir, yani birle┼čtirilmi┼č s├Âzl├╝k gibi davranan bir nesne tam olarak hesaplamadan olur. Yani, birle┼čtirilmi┼č s├Âzl├╝─č├╝n tembel bir versiyonu.

Python'da bu olduk├ža basittir ve yaz─▒m─▒n sonunda g├Âsterilen kodla yap─▒labilir. Bu verilen, as─▒l sorunun cevab─▒ ┼č├Âyle olacakt─▒r:

 z = MergeDict(x, y)
 

Bu yeni nesneyi kullan─▒rken, birle┼čtirilmi┼č bir s├Âzl├╝k gibi davran─▒r, ancak orijinal s├Âzl├╝kleri el de─čmeden b─▒rak─▒rken s├╝rekli olu┼čturma s├╝resi ve sabit bellek alan─▒ olur. Yaratmak, ├Ânerilen di─čer ├ž├Âz├╝mlerden ├žok daha ucuz.

Elbette, sonucu ├žok kullan─▒rsan─▒z, bir noktada ger├žek bir birle┼čtirilmi┼č s├Âzl├╝k olu┼čturman─▒n daha h─▒zl─▒ bir ├ž├Âz├╝m olaca─č─▒ s─▒n─▒r─▒na ula┼čacaks─▒n─▒z. Dedi─čim gibi, kullan─▒m durumunuza ba─čl─▒.

Ger├žek bir birle┼čmeyi tercih edece─činizi hissetmi┼č olsayd─▒n─▒z dict , ├ža─čr─▒ yapmak dict(z) onu ├╝retecekti (ama elbette di─čer ├ž├Âz├╝mlerden ├žok daha maliyetli, bu y├╝zden bu sadece bahsetmeye de─čer).

Bu s─▒n─▒f─▒ ayr─▒ca bir t├╝r kopyala-yaz s├Âzl├╝─č├╝ yapmak i├žin de kullanabilirsiniz:

 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}
 

─░┼čte d├╝z ileri kod 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())
 

5


2016-05-18

─░lgili yay─▒nlar


─░ki diziyi JavaScript'te birle┼čtirme ve yinelenen ├Â─čeleri kald─▒rma

Python'da yeni bir s├Âzl├╝k olu┼čturmak i├žin iki s├Âzl├╝k nas─▒l birle┼čtirilir? [├žift]

.NET'te iki diziyi birle┼čtirme

Bash iki sat─▒r sat─▒r sat─▒r nas─▒l birle┼čtirilir

─░ki s─▒ral─▒ diziyi s─▒ral─▒ bir dizide birle┼čtirmek nas─▒l yap─▒l─▒r? [kapal─▒]

─░ki ÔÇťarÔÇŁ statik k├╝t├╝phanesini bire birle┼čtirmek nas─▒l?

─░ki php nas─▒l birle┼čtirilir? Doctrine 2 ArrayCollection ()

─░ki PDF dosyas─▒n─▒ Java'daki bir dosyada birle┼čtirmek nas─▒l?

Git'te farkl─▒ dizin hiyerar┼čileri olan iki dal nas─▒l birle┼čtirilir?

iki dosyay─▒ tutarl─▒ bir ┼čekilde sat─▒r sat─▒r birle┼čtirme

Etiketle ilgili di─čer sorular [python]


Nesne de─či┼čmezleri / ba┼člat─▒c─▒lar─▒nda ├Âz referanslar

Docker kapsay─▒c─▒s─▒n─▒n dosya sistemini ke┼čfetme

Nas─▒l d├╝zeltilir: ÔÇťPageHandlerFactory-IntegratedÔÇŁ i┼čleyicisi mod├╝l listesinde k├Ât├╝ bir ÔÇťManagedPipelineHandlerÔÇŁ mod├╝l├╝ne sahip

JQuery'de onay kutusu de─čerini al─▒n

C i┼čaret├ži dizisine / i┼čaret├žiler dizisinin netle┼čtirilmemesi

Y├╝r├╝t├╝lmekte olan y├Ântemin ad─▒n─▒ alma

Git ├žak─▒┼čmas─▒n─▒ ikili dosyalarla ├ž├Âzme

─░fade ve ─░fadeye Kar┼č─▒

Takma ad m─▒ yoksa alias_method kullanmal─▒ m─▒y─▒m?

Xcode'da [Dosyaya gitÔÇŽ] var m─▒?