9

にマージし、我々はDictのは、Python 3.5ではdictの理解

>>> d1 = {1: 'one', 2: 'two'} 
>>> d2 = {3: 'three'} 
>>> {**d1, **d2} 
{1: 'one', 2: 'two', 3: 'three'} 

はクール開梱ダブルスプラットを使用してdictsをマージすることができます。しかし、動的なユースケースに一般化していないようです:

>>> ds = [d1, d2] 
>>> {**d for d in ds} 
SyntaxError: dict unpacking cannot be used in dict comprehension 

は、代わりに、私たちはたくさんの醜い思われる、reduce(lambda x,y: {**x, **y}, ds, {})を行う必要があります。その表現にあいまいさがないように思われないときに、パーサーが「それを行うための明白な方法」をなぜ許可しないのですか?

+1

他の*または**アンパックコンテキストでもこの操作を行うことはできません。つまり、some_function(xはlist_listsのxに対して) 'を行うことはできません。アンパック星は実際の演算子ではなく、式では出現できません。 – BrenBarn

+2

'{k:dの[d1、d2]のk、vのd.items()}'はあなたの 'reduce()'の代わりになりますが、まだ "醜い"です。 –

+2

私は個人的に好きではない 'dict(ChainMap(d2、d1))'という別の選択肢があると信じています。 –

答えて

6

それは正確にあなたの質問への答えではないのですが、私は(インラインの辞書をマージ)あなたが提案する何をすべきか慣用的かつエレガントな方法であることをChainMapを使用して検討したい:それはないですが

>>> d1 = {1: 'one', 2: 'two'} 
>>> d2 = {3: 'three'} 
>>> ds = [d1, d2] 
>>> dict(ChainMap(*ds)) 
{1: 'one', 2: 'two', 3: 'three'} 

多くのプログラマーがChainMapの仕組みを正確に把握していない可能性があるため、特に透過的なソリューションです。 「@AnttiHaapalaが指摘しているように」「最初に見つかったものが使用されています」ということに注意してください。reversedに電話をかけてdictChainMapに渡す必要があります。

>>> d2 = {3: 'three', 2:'LOL'} 
>>> dict(ChainMap(*ds)) 
{1: 'one', 2: 'two', 3: 'three'} 

>>> dict(ChainMap(*reversed(ds))) 
{1: 'one', 2: 'LOL', 3: 'three'} 
3

私には、明白な方法は次のとおりです。

d_out = {} 
for d in ds: 
    d_out.update(d) 

これは、迅速かつおそらくかなりのパフォーマンスです。私はPython開発者のために話すことができるかどうかはわかりませんが、期待しているバージョンが読みやすくなっているかどうかはわかりません。たとえば、あなたの理解力は、:の不足のために私には分かりやすいように見えます。 FWIW、テクニカル理由(例:パーサーの曖昧さ)があるとは思わない。は理解のアンパックを行う形式を追加する。

明らかに、these forms were proposedですが、(まだ)それらの実装を正当化するのに十分普遍的なサポートはありませんでした。

+0

ステートメントではなく式にすることで、機能スタイルのユースケースが増えます。 forループが常に優れていれば、マージ式をまったく追加する必要はありません。私の質問は、意図的に既知の所定数のオペランドに意図的に限定された理由です。 – wim

+0

@wim - 機能的なアプローチでこれをやりたいのであれば、これを関数内にラップしてください:-)。関連するPEPで議論されているように、意図的に制限された理由は、使用する構文についてコミュニティに十分なコンセンサスがなかったためです。多分将来、それはいつか再訪されるだろうが、今のところそれは省略され、誰もが同意した部分を実施予定にすることができる。 – mgilson

関連する問題