我试图确定字典中是否存在特定的键和值对;但是,如果我使用contains或has key方法,它只检查键。我需要它来检查键和特定值。一些背景:我们总共有4个字典:一个用于A、B、CompareList和ChangeList。一旦A被初始化,我将A的内容放入比较列表(我将直接比较它们;但是A和B是双哈希表)。我试过这里所有的方法,但没有一个对我有用)。所以一旦我们将a放入comparelist中,我将它与b中的objecttributes字典进行比较,看看是否有什么变化。例如,B可能有键,值对shape:circle和fill:no。如果compareList有shape:circle和fill:yes,那么我只希望fill:yes是changelist。问题在于"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("
")
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"
key in dictionary and dictionary[key] == value出了什么问题?
这种方式的问题(我应该早点指定)是因为我正在做很多迭代,在if语句中使用"and"会增加时间。我们必须尽可能地优化;所以对于已经很复杂的问题,任何额外的开销都是不好的。谢谢你的帮助。
真的?创建新的Try/Except堆栈(在接受的答案中)比一个简单的小and操作符更快?我想在您的案例中,键几乎总是存在的,或者编译器可以更好地优化它。什么是时间差异,你的分析PLZ-是改善的数量顺序?
@Elijahphilpotts:有疑问时,请描述一下。key in dictionary和dictionary[key] == value都是在C中实现的。除了在python级别的函数中,额外的尝试成本应该会降低checkKeyValuePairExistence的效率。
@我在回答中加了一些时间。过来看。
最后我取消了功能,你说得对。我一直被告知脚本语言比C++慢得多,所以我不确定这是真的。谢谢你的帮助。
使用
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总是较慢的(在我的系统上,当键值对不存在时,大约是16x时的2倍)。我还测试了越来越大和越来越小的字典,发现时间安排变化不大。
>>> 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
值得注意的是,作为get的第二个论点的not value是否使不存在的密钥不等于None(还有其他原因吗?)
@阿普里略:对。如果密钥不在字典中,并且测试的值是None,d.get(key) == value将错误地评估为True。
不正确,但有时可能有用——在这种情况下,最好把它明确地写为if value == None and key not in d ...,以防止将来的头痛:)
谢谢你的帮助。最后我使用了类似于第二种方法的方法。
@elijahphilpotts:if key in d and d[key] == value是一种基本的惯用Python,不需要封装在名为checkKeyValuePairExistence的函数中。(当然,这是一个品味问题。)
这个功能怎么样:
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
- 1。这否定了字典的一个主要优点——高效的成员测试。当出现键值对时,平均搜索需要访问一半的项目。它需要搜索所有项目,以确定找不到键值对。
已经提供了一个尝试例外的示例。我只是添加了一个不同的例子
这并不是真正的"另一个例子"。我认为这是个错误的答案。其他人可能不同意并赞成。(另外,我在你的答案中编辑了一个空格,因为我不小心把它投了赞成票,而不是投了反对票。我无法更改我的投票,除非它被编辑。)
嘿,这是OP要求的