Python 检查字典中是否存在特定键和值

Python 检查字典中是否存在特定键和值,python,dictionary,Python,Dictionary,我试图确定字典中是否存在特定的键和值对;但是,如果我使用contains或has key方法,它只检查键。我需要它来检查键和特定值。一些背景: 我们一共有4本字典:一本用于a、B、CompareList和ChangeList。初始化A后,我将A的内容放入CompareList(我会直接比较它们;但A和B是双哈希表。我在这里尝试了所有方法,但没有一种对我有效)。所以,一旦我们将A放入CompareList,我将它与B中的ObjectAttributes字典进行比较,看看是否有任何变化。例如,B可能

我试图确定字典中是否存在特定的键和值对;但是,如果我使用contains或has key方法,它只检查键。我需要它来检查键和特定值。一些背景: 我们一共有4本字典:一本用于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是变更列表。问题在于“if attributes.getName()不在self.CompareList:”行中。这是代码;我正在Python2.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"
使用

或者(仅在Python 3中)

在Python3中,d.items()返回a,它支持快速成员身份测试。在Python2
d.items()
中,返回一个列表,该列表创建和测试成员资格都很慢。Python2.7是一个特例,您可以使用
d.viewitems()
并获得与Python3中使用
d.items()
相同的结果

编辑:在注释中,您表示出于性能原因,您更喜欢
checkKeyValuePairExistence
而不是
输入d和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 

这个功能怎么样:

def checkKeyValuePairExistence(dic, key, value):
    try:
        return dic[key] == value
    except KeyError:
        return False
如果您使用的是python提供的词典以外的另一种词典(很抱歉,如果您使用或不使用,我无法从您的帖子中理解),请告诉我,我将尝试为您提供另一种解决方案

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

字典中的
键和字典中的[key]==value有什么问题吗?这种方法的问题(我应该在前面指定)是因为我进行了大量迭代,在if语句中使用“and”会增加时间。我们必须尽可能地优化;因此,对于已经复杂的问题,任何额外的开销都是不好的。谢谢你的帮助,真的吗?在您的情况下,创建新的try/except堆栈(如接受的答案)比简单的
操作符更快?我想在您的案例中,密钥几乎总是存在的,或者编译器可以更好地优化它。。与你的剖面plz相比,时间上有什么不同?是按照数量级的顺序改进吗?@ElijahPhilpotts:当有疑问时,剖面。
key-in-dictionary
dictionary[key]==value
都是用C实现的。除了Python级别的函数外,额外的尝试成本应该会降低
checkKeyValuePairExistence
的效率。@ElijahPhilpotts:我在答案中添加了一些计时。检查它。可能值得注意的是,
get
的第二个参数
not value
用于使不存在的键不等于
None
(还有其他原因吗?@Aprillion:Correct。如果键不在字典中,并且测试的值为
None
d.get(key)==value
将错误地计算为
True
,但有时它可能很有用——在这种情况下,如果value==None,最好显式编写为
if value==None,并在d中输入not…
,以避免将来的麻烦:)谢谢您的帮助。我最终使用了与第二种方法类似的方法。@ElijahPhilpotts:
如果d中的键和d[key]==value
是一种基本的惯用Python,它不需要封装在名为
checkKeyValuePairExistence
的函数中。(当然,这是一个品味的问题。这否定了字典的一个主要优点——有效的成员资格测试。当存在键值对时,平均搜索需要访问一半的项。它需要搜索所有项目以确定找不到键值对。已提供了“除此之外重试”示例。我只是增加了一个不同的例子,这并不是“只是另一个例子”。我认为这是一个糟糕的答案。其他人可以不同意并投票。(另外,我在你的答案中编辑了一个空格,因为我不小心投了上票而不是下票。除非经过编辑,否则我无法更改我的投票。)嘿,这是OP要求的
def checkKeyValuePairExistence(dic, key, value):
    try:
        return dic[key] == value
    except KeyError:
        return False
a = {1:'a', 2:'b'}
b = (1, 'a')
print b in a.iteritems() # prints True