如何在Python字典上执行设置操作? [英] How can I perform set operations on Python dictionaries?

查看:56
本文介绍了如何在Python字典上执行设置操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然在字典的键之间进行设置操作非常有用,但我经常希望我可以对字典本身执行设置操作.

While it is incredibly useful to be able to do set operations between the keys of a dictionary, I often wish that I could perform the set operations on the dictionaries themselves.

我发现了一些食谱,可以两种词典的区别但是我发现这些内容很冗长,并认为必须有更多的Python答案.

I found some recipes for taking the difference of two dictionaries but I found those to be quite verbose and felt there must be more pythonic answers.

推荐答案

tl; dr食谱: {k:d1.get(k,d1或d2 [k])for set(d1)中的k|set(d2)} | 可以用任何其他set运算符替换.

tl;dr Recipe: {k:d1.get(k, k in d1 or d2[k]) for k in set(d1) | set(d2)} and | can be replaced with any other set operator.

基于@torek的注释,另一个可能更容易记住的食谱(虽然完全通用)是: {k:d1.get(k,d2.get(k))for set(d1)中的k|set(d2)} .

Based @torek's comment, another recipe that might be easier to remember (while being fully general) is: {k:d1.get(k,d2.get(k)) for k in set(d1) | set(d2)}.

下面的完整答案:

我的第一个答案未正确处理评估为False的值.这是处理Falsey值的改进版本:

My first answer didn't deal correctly with values that evaluated to False. Here's an improved version which deals with Falsey values:

>>> d1 = {'one':1, 'both':3, 'falsey_one':False, 'falsey_both':None}
>>> d2 = {'two':2, 'both':30, 'falsey_two':None, 'falsey_both':False}
>>> 
>>> print "d1 - d2:", {k:d1[k] for k in d1 if k not in d2}                  # 0
d1 - d2: {'falsey_one': False, 'one': 1}
>>> print "d2 - d1:", {k:d2[k] for k in d2 if k not in d1}                  # 1
d2 - d1: {'falsey_two': None, 'two': 2}
>>> print "intersection:", {k:d1[k] for k in d1 if k in d2}                      # 2
intersection: {'both': 3, 'falsey_both': None}
>>> print "union:", {k:d1.get(k, k in d1 or d2[k]) for k in set(d1) | set(d2)}   # 3
union: {'falsey_one': False, 'falsey_both': None, 'both': 3, 'two': 2, 'one': 1, 'falsey_two': None}

union 的版本是最通用的版本,可以将其转换为功能:

The version for union is the most general and can be turned into a function:

>>> def dict_ops(d1, d2, setop):
...     """Apply set operation `setop` to dictionaries d1 and d2
... 
...     Note: In cases where values are present in both d1 and d2, the value from
...     d1 will be used.
...     """
...     return {k:d1.get(k,k in d1 or d2[k]) for k in setop(set(d1), set(d2))}
... 
>>> print "d1 - d2:", dict_ops(d1, d2, lambda x,y: x-y)
d1 - d2: {'falsey_one': False, 'one': 1}
>>> print "d2 - d1:", dict_ops(d1, d2, lambda x,y: y-x)
d2 - d1: {'falsey_two': None, 'two': 2}
>>> import operator as op
>>> print "intersection:", dict_ops(d1, d2, op.and_)
intersection: {'both': 3, 'falsey_both': None}
>>> print "union:", dict_ops(d1, d2, op.or_)
union: {'falsey_one': False, 'falsey_both': None, 'both': 3, 'two': 2, 'one': 1, 'falsey_two': None}

两个字典中都有项目时,将使用 d1 中的值.当然,我们可以通过更改函数参数的顺序来从 d2 返回值.

Where items are in both dictionaries, the value from d1 will be used. Of course we can return the value from d2 instead by changing the order of the function arguments.

>>> print "union:", dict_ops(d2, d1, op.or_)
union: {'both': 30, 'falsey_two': None, 'falsey_one': False, 'two': 2, 'one': 1, 'falsey_both': False}

这篇关于如何在Python字典上执行设置操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆