6

ディクショナリのキー間で集合操作を実行できることは非常に便利ですが、辞書自体で集合操作を実行できればと思うことがよくあります。

2 つの辞書の違いを取るためのレシピをいくつか見つけましたが、それらは非常に冗長であることがわかり、もっと Pythonic な答えが必要だと感じました。

4

3 に答える 3

3

編集: ここのレシピは False 値を正しく処理しません。別の改善された回答を提出しました。

ここに私が思いついたいくつかのレシピがあります:

>>> d1 = {'one':1, 'both':3}
>>> d2 = {'two':2, 'both':30}
>>> 
>>> print "d1 only:", {k:d1.get(k) or d2[k] for k in set(d1) - set(d2)}     # 0
d1 only: {'one': 1}
>>> print "d2 only:", {k:d1.get(k) or d2[k] for k in set(d2) - set(d1)}     # 1
d2 only: {'two': 2}
>>> print "in both:", {k:d1.get(k) or d2[k] for k in set(d1) & set(d2)}     # 2
in both: {'both': 3}
>>> print "in either:", {k:d1.get(k) or d2[k] for k in set(d1) | set(d2)}   # 3
in either: {'both': 3, 'two': 2, 'one': 1}

#0 と #2 の式はもっと単純にすることもできますが、この式の一般性が気に入っています。これにより、このレシピをどこにでもコピー アンド ペーストし、最後に set 操作を必要なものに変更するだけで済みます。

もちろん、これを関数に変換できます。

>>> def dict_ops(d1, d2, setop):
...     return {k:d1.get(k) or d2[k] for k in setop(set(d1), set(d2))}
... 
>>> print "d1 only:", dict_ops(d1, d2, lambda x,y: x-y)
d1 only: {'one': 1}
>>> print "d2 only:", dict_ops(d1, d2, lambda x,y: y-x)
d2 only: {'two': 2}
>>> import operator as op
>>> print "in both:", dict_ops(d1, d2, op.and_)
in both: {'both': 3}
>>> print "in either:", dict_ops(d1, d2, op.or_)
in either: {'both': 3, 'two': 2, 'one': 1}
>>> print "in either:", dict_ops(d2, d1, lambda x,y: x|y)
in either: {'both': 30, 'two': 2, 'one': 1}
于 2013-07-17T07:57:13.963 に答える
-1

さらにいくつかの例を次に示します。

セット追加d1 + d2

{key: value for key, value in d1.items() + d2.items()}
# here values that are present in `d1` are replaced by values in `d2`

あるいは、

d3 = d1.copy()
d3.update(d2)

セット差d1 - d2

{key: value for key, value in d1.items() if key not in d2}
于 2013-07-17T08:17:24.147 に答える