字典中的复合键

2024-05-18 05:14:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在维护一个字典,它可以记录成对对象之间的相似性。
例如,此字典可以如下所示:

similarities = {
 p1: {p2: v12, p3:v13, p4:v14},
 p2: {p1: v21, p3:v23, p4:v24},
 p3: {p1: v31, p2:v32, p4:v34},
 p4: {p1: v41, p2:v42, p4:v43}
}

注意,相似性度量是对称的。因此,similarities[p1][p2]与{}相同,即v12 == v21。在

有时,我需要从similarities[p1]中删除{};在这样做时,我还需要从similarities中的所有内部词典中删除{}和{}。
这既单调又低效。在

因此,有没有一种方法可以用复合键来维护字典,这样我就可以查找similarities[p1,p2]?在

我真的不能使用tuple,因为(p1, p2) != (p2, p1)我也不知道如何对元组排序。在

一个frozenset是我能想到的唯一的其他容器,但这并不能切断它,因为{}中可能还有其他键包含{}或{}作为组件。那么我可以用什么容器来解决这个问题呢?在

技术信息:

  • python 2.7
  • “复合键”中始终有两个元素

谢谢你


Tags: 对象字典记录相似性容器p2p3p1
3条回答

我可能只使用frozenset,假设对象是散列的。在

或者,如果它们有任何定义良好且一致的顺序,则可以将它们保存在按所述顺序排序的元组中。如果您愿意,您可以编写一个小的dict子类来透明地完成这项工作。在

或者,你可以这样做:

class SymmetricDict(dict):
    def __getitem__(self, key):
        if key in self:
            return dict.__getitem__(self, key)
        a, b = key
        return dict.__getitem__(self, (b, a))

对于__setitem__,也是类似的。在

我认为使用frozenset是唯一合理的解决方案。您可以使用集合交集测试的理解来找到只与其中一个值匹配的键:

def remove_ab(ab, similarities):
    return {k:v for k, v in similarities.items() if not ab & k}

similarities = {frozenset({1, 2}): "v12",
                frozenset({1, 3}): "v13",
                frozenset({2, 3}): "v23",
                frozenset({3, 4}): "v34"}

similarities = remove_ab(frozenset({1, 2}), similarities
print(similarities) # output is {frozenset({3, 4}): 'v34'}

如果p帴objects是支持排序的类型,那么您可以使用一个tuple,其中两个元素总是以lo>;hi顺序排列吗?在

相关问题 更多 >