检查字典中是否存在特定键及其对应的值

5 投票
3 回答
34858 浏览
提问于 2025-04-20 07:15

我想知道在一个字典里是否存在特定的键值对;但是如果我用包含(contains)或者有键(has-key)的方法,它们只检查键而不检查具体的值。我需要同时检查键和特定的值。这里有点背景信息:

我们总共有四个字典:一个是A,一个是B,还有CompareList和ChangeList。当A被初始化后,我会把A的内容放到CompareList里(我本来想直接比较它们,但A和B是双重哈希表。我试过这里所有的方法,但都不管用)。所以当我们把A放进CompareList后,我会把它和B里的ObjectAttributes字典进行比较,看看有没有变化。举个例子,B可能有键值对shape:circle和fill:no。如果CompareList里有shape:circle和fill:yes,那么我只想把fill:yes放到ChangeList里。问题出在“if attributes.getName() not in self.CompareList:”这一行。以下是代码;我在Python 2.7.8上运行它。提前感谢任何帮助!!

class ObjectSemanticNetwork:
    def __init__(self):
        self.ObjectNames = {}
        self.ObjectAttributes = {}

    def setName(self, name):
        self.ObjectNames[name] = self.ObjectAttributes

    def setData(self, name, attribute):
        self.ObjectAttributes[name] = attribute

    def checkData(self, key):
        print(key)
        for key, value in self.ObjectAttributes.iteritems():
            print(key)
            print(value)
            print("\n")
class Agent:
(self):
        self.CompareList = {}
        self.ChangeListAB = {}
        self.ChangeListCD = {}

    def addToCompareList(self, name, value):
        self.CompareList[name] = value

    def addToChangeListAB(self, name, value):
        self.ChangeListAB[name] = value

    def addToChangeListCD(self, name, value):
        self.ChangeListCD[name] = value

    def CheckList(self, List, ListName):
        print '-------------------------',ListName,'--------------------------------'
        for key, value in List.iteritems():
            print(key)
            print(value)

    def Solve(self,problem):
        OSNAB = ObjectSemanticNetwork()
        for object in problem.getFigures().get("A").getObjects():
            for attributes in object.getAttributes():
                self.addToCompareList(attributes.getName(), attributes.getValue())
                OSNAB.ObjectNames["A"] = OSNAB.setData(attributes.getName(), attributes.getValue())
        #OSNAB.checkData("A")
        self.CheckList(self.CompareList,"CompareList")

        for object in problem.getFigures().get("B").getObjects():
            for attributes in object.getAttributes():
                if attributes.getName() not in self.CompareList:
                    self.addToChangeListAB(attributes.getName(), attributes.getValue())
                OSNAB.ObjectNames["B"] = OSNAB.setData(attributes.getName(), attributes.getValue())
        # OSNAB.checkData("B")
        self.CheckList(self.ChangeListAB,"ChangeList")

        OSNCD = ObjectSemanticNetwork()
        for object in problem.getFigures().get("C").getObjects():
            for attributes in object.getAttributes():
                OSNCD.ObjectNames["C"] = OSNCD.setData(attributes.getName(), attributes.getValue())
        # OSNCD.checkData("C")

        for object in problem.getFigures().get("1").getObjects():
            for attributes in object.getAttributes():
                OSNCD.ObjectNames["D"] = OSNCD.setData(attributes.getName(), attributes.getValue())
        # OSNCD.checkData("D")

        return "6"

3 个回答

0

为什么不直接这样做呢:

a = {1:'a', 2:'b'}
b = (1, 'a')
print b in a.iteritems() # prints True
12

使用

if key in d and d[key] == value:

或者(仅适用于Python 3)

if (key, value) in d.items():

在Python 3中,d.items()会返回一个字典视图对象,这个对象可以快速检查某个元素是否存在。而在Python 2中,d.items()返回的是一个列表,这样创建起来比较慢,检查元素是否存在也比较慢。Python 2.7是个特例,你可以使用d.viewitems(),这样得到的结果和Python 3中的d.items()是一样的。

编辑:在评论中你提到出于性能考虑,你更喜欢使用checkKeyValuePairExistence,而不是key in d and d[key] == value。下面是一些时间测试,显示checkKeyValuePairExistence总是更慢(在我的系统上,当键值对存在时慢约2倍,当不存在时慢16倍)。我还测试了更大和更小的字典,发现时间差异不大。

>>> import random
>>> from timeit import timeit
>>> def checkKeyValuePairExistence(dic, key, value):
...     try:
...         return dic[key] == value
...     except KeyError:
...         return False
...
>>> d = {random.randint(0, 100000):random.randint(0, 100000) for i in range(1000)}
>>> setup = 'from __main__ import k, d, v, checkKeyValuePairExistence'
>>> test_try_except = 'checkKeyValuePairExistence(d, k, v)'
>>> test_k_in_d_and = 'k in d and d[k] == v'
>>> k, v = random.choice(d.items()) # to test if found
>>> timeit(test_try_except, setup=setup)
0.1984054392365806
>>> timeit(test_k_in_d_and, setup=setup)
0.10442071140778353
>>> k = -1 # test if not found
>>> timeit(test_try_except, setup=setup)
1.2896073903002616
>>> timeit(test_k_in_d_and, setup=setup)
0.07827843747497809 
2

这个函数怎么样:

def checkKeyValuePairExistence(dic, key, value):
    try:
        return dic[key] == value
    except KeyError:
        return False

如果你使用的是其他类型的字典,而不是Python自带的那种(抱歉,我没能从你的帖子中理解你到底在用哪种),那请告诉我,我会尽量给你提供另一个解决方案。

撰写回答