2014-09-07 6 views
0

사전에 특정 키와 값 쌍이 있는지 확인하려고합니다. 그러나 contains 또는 has-key 메서드를 사용하면 키를 확인하기 만합니다. 키와 특정 값을 모두 확인해야합니다. 배경 : A, B, CompareList 및 ChangeList에 대해 총 4 개의 사전이 있습니다. 일단 A가 초기화되면 A의 내용을 CompareList에 저장합니다 (직접 비교할 것입니다. 그러나 A와 B는 이중 해시 테이블이며 모든 메서드를 시도했지만 그 중 아무 것도 작동하지 않습니다). 따라서 A를 CompareList에 넣으면 B의 ObjectAttributes 사전과 비교하여 변경된 사항이 있는지 확인합니다. 예를 들어, B는 키, 값 쌍 모양을 가질 수 있습니다 : circle 및 fill : no. CompareList에 shape : circle 및 fill : yes가 있으면 ChangeList 만 fill : yes로 지정합니다. 문제는 "if attribute.getName() not self.CompareList :"행에 있습니다. 다음은 코드입니다. Python 2.7.8에서 실행하고 있습니다. 사전에 어떤 도움을 주셔서 감사합니다 !! 파이썬 3 d.items()에서특정 키와 값이 사전에 있는지 확인하십시오.

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

사전에 키가 있고 사전에 [key] == value'가있는 g? – Aprillion

+0

이런 식의 문제 (그리고 이전에 지정 했어야 했음)는 반복문을 많이 사용하기 때문에 if 문에 "and"를 사용하면 시간이 늘어납니다. 가능한 한 많이 최적화해야합니다. 이미 복잡한 문제에 대한 추가 오버 헤드가 나쁘다. 도와 줘서 고맙다. –

+0

정말요? 새로운 시도/예외 스택을 만드는 것 (받아 들인 대답 에서처럼)은 간단한 작은'and' 연산자보다 더 빠릅니까? 키가 거의 항상 이미 존재하거나 아마도 컴파일러가 그것을 더 잘 최적화 할 수 있다고 생각합니다. 프로파일 링 PLZ와의 타이밍 차이는 무엇입니까? - 크기 순서의 개선입니까? – Aprillion

답변

1

방법이 기능에 대해 :

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

다른 사전의 다른 유형을 사용하는 경우 다음 중 하나 파이썬 제공 (당신이 그것을 사용하는 경우 미안, 난 당신의 게시물에서 이해 couldnt는거야 여부)를 알려 주시면 다른 솔루션을 제공하기 위해 노력하겠습니다

4

사용

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

또는 (단지 파이썬 3)

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

빠른 회원 테스트를 지원하는 Dictionary view object을 반환합니다. Python 2에서 d.items()은 생성 속도가 느리고 멤버쉽 테스트 속도가 느린 목록을 반환합니다. 성능상의 이유로 당신이 key in d and d[key] == value 이상 checkKeyValuePairExistence를 선호하는 당신이 나타 코멘트에서 : 파이썬 2.7는 d.viewitems()을 사용하고

편집 파이썬 3에서 d.items()으로 얻을 같은 일을 얻을 수있는 특별한 경우이다. 다음은 checkKeyValuePairExistence이 항상 느리다는 것을 보여주는 몇 가지 타이밍입니다 (키 - 값 쌍이 존재하지 않을 때 16x가있을 때 내 시스템에서 약 2x 정도). 나는 또한 더 크고 더 작은 사전을 시험했고 타이밍에 약간의 변화를 발견했다.

>>> 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 
+0

'get'의 두 번째 인자로'not value'가 존재하지 않는 키를'None'과 같지 않게 만드는 것이 주목할 것입니다 (다른 이유는 무엇입니까?) – Aprillion

+0

@Aprillion : 올바른 것입니다. 만약 키가 사전에 없으며 테스트 된 값이'None'이라면'd.get (key) == value'는'True'로 잘못 평가됩니다. –

+0

가 잘못되었지만 때로는 유용 할 수도 있습니다.이 경우 나중에 두통을 막기 위해 'if value == None 및 D not key로 명시 적으로 작성하는 것이 더 좋습니다. :) – Aprillion

-1

바로이 작업을 수행 할 이유 :

이 wron을 무엇
a = {1:'a', 2:'b'} 
b = (1, 'a') 
print b in a.iteritems() # prints True 
+0

-1. 이것은 사전의 주요 장점 중 하나 인 효율적인 회원 테스트를 무효화합니다. 키 - 값 쌍이 표시되면 평균 검색은 항목의 절반을 방문해야합니다. 키 - 값 쌍이 발견되지 않았다는 것을 결정하기 위해 모든 항목을 검색해야합니다. –

+0

try-except 예제가 이미 제공되었습니다. 나는 단지 다른 예를 더하고있다. – ZWiki

+0

정말 "단지 다른 예"는 아니다. 나는 그것이 나쁜 대답이라고 믿는다. 다른 사람들은 반대하고 upvote 수 있습니다. (편집하지 않는 한 우연히 upvoted 때문에 투표를 수정했습니다. 편집하지 않으면 투표를 변경할 수 없습니다.) –

관련 문제