Python dicts的交叉点更新?

Python dicts的交叉点更新?,python,dictionary,intersection,Python,Dictionary,Intersection,我想要一个dictionary类,它实现一个intersection\u update方法,在精神上类似于dict.update,但只将更新限制在调用实例中已经存在的键上(参见下面的一些示例实现) 但是,本着避免车轮改造的精神,在我开始实现(并编写测试等)具有此附加功能的映射类之前,类似的东西是否已经存在于或多或少的标准模块中 明确地说,我想到的intersection\u update方法将执行以下操作: def intersection_update(self, other): f

我想要一个dictionary类,它实现一个
intersection\u update
方法,在精神上类似于
dict.update
,但只将更新限制在调用实例中已经存在的键上(参见下面的一些示例实现)

但是,本着避免车轮改造的精神,在我开始实现(并编写测试等)具有此附加功能的映射类之前,类似的东西是否已经存在于或多或少的标准模块中


明确地说,我想到的
intersection\u update
方法将执行以下操作:

def intersection_update(self, other):
    for k in self.viewkeys() & other.viewkeys():
        self[k] = other[k]
…尽管实际实施可能会尝试一些可能的优化,例如:

def intersection_update(self, other):
    x, y = (self, other) if len(self) < len(other) else (other, self)
    for k in x.iterkeys():
        if k in y:
            self[k] = other[k]
def交叉口_更新(自身、其他):
x、 y=(自身,其他)如果len(自身)

编辑:在这篇文章的原始版本中,我曾写过“或者,是否有一种标准的Python习惯用法可以避免实现[class with a
intersection\u update
]方法?”但我几乎立即删除了它,因为经过进一步思考,我意识到这是一种对弱答案的邀请,因为我对Python语言的“核心”了解得足够多,所以我非常确定不存在这样的习惯用法,至少没有一种习惯用法能够与专用方法的优点(通用性、易读性、易于键入)相匹配。

这里有一个伪代码,可以与现有的更新函数一起使用,但是,如果您想扩展字典,那么您的代码段也是有效的——但这会增加到处使用dict类的额外麻烦

In [1]: x = dict(name='abc', age=23)

In [2]: y = dict(name='xyz', notes='Note 123', section=None)

In [3]: #x.update(dict((k,y[k]) for k in y if k in x))

In [3]: x.update((k,v) for k,v in y.iteritems() if k in x)

In [4]: x
Out[4]: {'age': 23, 'name': 'xyz'}
编辑:根据kjo的注释,使用iteritems方法更新代码

def dict_intersection(d1, d2):
    return dict((key, d2[key] or d1[key]) for key in frozenset(d1) & frozenset(d2))
或者,对于python版本>=2.7:

def dict_intersection(d1, d2):
    return {key: d2[key] or d1[key] for key in d1.viewkeys() & d2.viewkeys()}

出于好奇,为什么
frozenset
而不是
set
?另外,在2.7中,
dict.viewkeys
返回的对象设置为like,并支持
&
|
本地操作。您是对的,在>=2.7中您可以使用
d1.viewkeys()&d2.viewkeys()
。根据您的编辑,我想您知道
d1。更新((k,v)对于d2中的k,v,如果d1中的k)
。就个人而言,我认为上面的内容非常可读——事实上,我想说,乍一看,上面的内容比
d1.intersection\u update(d2)
更明显。如果我看到了
d1.intersection\u update(d2)
,我必须去看文档以确定。@senderle:是的,但当我第一次看到
set.intersection\u update时,我还必须看文档。关键是,一旦人们知道d1.update(d2)
的作用,那么读取它是立即的,而当人们遇到类似于d1.update(k,v)的东西时((k,v)表示d2中的k,v,如果d1中的k)
在源代码中,人们总是必须逐个部分地解析表达式才能确定它的作用。诚然,一个人从一个单独的方法中获得的任何易读性的提高本身都太小,不足以保证拥有它。是的,我很熟悉这个习惯用法。我更喜欢这个变体:
x.update((k,v)表示k,v在y.iteritems()表示k在x中)
。(请注意,它不会创建中间
dict
)。顺便说一句,在我发布问题后,我立即删除了询问习语的行,这些习语可能与
intersection\u update
方法的目的相同,但从您的回答来看,我似乎不够快。很抱歉。