2013-10-03 6 views
0

나는 하나의 다른 사전과 비교해야하는 미리 설정된 양의 목록이 있습니다.사전 목록을 다른 사전과 결합

list1 = [ 
    {'X1': 'Q587', 'X2': 'Q67G7', ...}, 
    {'AB1': 'P5K7', 'CB2': 'P678', ...}, 
    {'B1': 'P6H78', 'C2': 'BAA5', ...}] 

dict1 = { 
    'X1': set([B00001,B00020,B00010]), 
    'AB1': set([B00001,B00007,B00003]), 
    'C2': set([B00001,B00002,B00003]), ... 
} 

은 내가 지금 갖고 싶어하는 키로 가진 새 사전입니다 :

그들은 (키와 값에 대한 구체적인 형태 나 패턴이 무작위로 선택되는 예는 없다) 다음과 같은 형태를 따른다 : list1에있는 사전의 값. dict1의 값을 값으로 사용합니다. 그리고 이것은 비교 된 사전에서 키가 교차 할 때에 만 가능합니다.

nDicts = len(list1) 
resultDict = {} 

    for key in range(0,nDicts): 
      for x in list1[key].keys(): 
       if x in dict1.keys(): 
        resultDict.update{list1[key][x]:dict1[x]} 
        print resultDict 

이 원하는 출력 형식이어야합니다 :

나는 다음과 같은 방법으로이 작업을 수행 한

resulDict = { 
     'Q587': set([B00001,B00020,B00010]), 
     'P5K7': set([B00001,B00007,B00003]), 
     'BAA5': set([B00001,B00002,B00003]), ... 
    } 

이 작동하지만 데이터의 양 때문에이 영원히 소요 너무 높다 . 더 좋은 방법이 있나요?

EDIT : 입력 값을 조금 변경했는데, 중요한 것은 list1 내의 사전과 dict1 내의 사전 사이에 교차하는 키뿐입니다.

+0

어느 것이 더 큽니까? 'list1' 또는'dict1'? – Hyperboreus

+1

'list1'에서 하나 이상의 사전에 나타나는 키가 있습니까? – Hyperboreus

+0

실제 샘플 데이터 (구문 오류가 아닌 평가되고 사용될 수 있음)와 원하는 출력을 표시 할 수 있습니까? – abarnert

답변

1

파이썬 2.x의 keys 메소드는 모든 키의 사본으로리스트를 만들고,의 각 dict에 대해서만이 작업을 수행합니다 (아마도 큰 문제는 아니지만, 당신의 데이터를 알지 못해서), 또한 dict1에 대해 반복적으로 그렇게합니다.

위의 경우 목록에서 in 테스트를 수행하면 일치 항목을 찾을 때까지 목록의 각 값을 확인해야하므로 사전에 in 테스트를 수행하는 것이 거의 즉각적입니다. 해시 값을 찾아야합니다.

keys 완전히 실제로 필요-반복 사전인가하는 것은 당신에게 순서대로 키를 제공합니다 (지정되지 않은 순서를하지만, 같은 keys()를 호출 마찬가지입니다), 그리고 DICT를 -checking in는 당신이 얻을 것 같은 키를 검색 keys(). 그래서, 그것들을 제거하는 것은 똑같은 일을하지만, 더 간단하고, 빠르며, 사용되는 메모리가 적습니다. 따라서 :

성능을 향상시키는 데 도움이되지는 않지만 아직 수행할만한 효과가있는이 방법을 단순화 할 수도 있습니다.

모든 인덱스의 거대한 목록을 작성하고 반복하는 대신 list1을 직접 반복 할 수 있습니다.

for list1_dict in list1: 
    for x in list1_dict: 
     if x in dict1: 
      resultDict = {list_dict[x]: dict1[x]} 
      print resultDict 

그리고 당신은 하나의 단계에서 키와 값을 얻을 수 있습니다 : 첫 번째 검사에 대한 두 배 당신이 대부분의 값은 찾아 볼 수 예상되는 경우 또한

for list1_dict in list1: 
    for k, v in list1_dict.iteritems(): 
     if k in dict1: 
      resultDict = {v: dict1[k]} 
      print resultDict 

는,이 걸릴 것이다 그 값을 찾은 다음 그것을 찾아보고 실패를 처리하려고 할 때 찾아보기 만하면됩니다. 그러나 대부분의 값이 이 아니고이 아닌 경우이 사실이 아닙니다.) 따라서 :

for list1_dict in list1: 
    for k, v in list1_dict.iteritems(): 
     try: 
      resultDict = {v: dict1[k]} 
      print resultDict 
     except KeyError: 
      pass 
+1

"dict을 반복하면 순서대로 키가 제공됩니다." 어떤 순서? – Hyperboreus

+0

이것은 OP의 코드 샘플이하는 일을보다 잘 수행합니다. 그러나 그것은 그의 질문이 요구했던 것, 즉 하나의 사전을 만드는 것을하지 않습니다. –

+0

@Hyperboreus : 지정되지 않은 순서이지만'keys() '가 준 순서와 같으며,이 경우 중요하지 않습니다. 요점을 명확히하기 위해 편집했습니다. – abarnert

1

설정 교차로를 사용하여 작업을 단순화하고 최적화 할 수 있습니다. 파이썬 2.7 사전 파이썬 3에서 dict.viewkeys() 방법을 사용하여 세트로 키를 나타냅니다, 또는 dict.keys() 수 있습니다

resultDict = {d[sharedkey]: dict1[sharedkey] 
       for d in list1 for sharedkey in d.viewkeys() & dict1} 

내가 당신을 가정입니다 : 이것은 심지어 DICT 이해로 전환 할 수

resultDict = {} 

for d in list1: 
    for sharedkey in d.viewkeys() & dict1: 
     resultDict[d[sharedkey]] = dict1[sharedkey] 

결과 키가 공유 키당 새로운 사전이 아니라 하나를 원했습니다. 샘플 입력에

데모 : 모두 X1AB1list1에 사전과 공유하지만 두 경우 모두, 결과 키가 AAA1입니다

>>> list1 = [ 
...  {'X1': 'AAA1', 'X2': 'BAA5'}, 
...  {'AB1': 'AAA1', 'CB2': 'BAA5'}, 
...  {'B1': 'AAA1', 'C2': 'BAA5'}, 
... ] 
>>> dict1 = { 
...  'X1': set(['B00001', 'B00002', 'B00003']), 
...  'AB1': set(['B00001', 'B00002', 'B00003']), 
... } 
>>> {d[sharedkey]: dict1[sharedkey] 
... for d in list1 for sharedkey in d.viewkeys() & dict1} 
{'AAA1': set(['B00001', 'B00002', 'B00003'])} 

참고. 이 중 하나만 최종 일치합니다. 그러나 dict1의 두 값은 정확히 같지만 어쨌든이 경우 임의의 확률을 생성하지 않습니다. 당신이 list1에 사전에 따라 별도의 사전을 원하는 경우

, 단순히 for d in list1: 루프를 이사 : 당신이 정말로 공유 키 당 하나 개의 사전을 원하는 경우

for d in list1: 
    resultDict = {d[sharedkey]: dict1[sharedkey] for sharedkey in d.viewkeys() & dict1} 
    if resultDict: # can be empty 
     print resultDict 

, 이동 다른 루프 아웃 :

for d in list1: 
    for sharedkey in d.viewkeys() & dict1: 
     resultDict = {d[sharedkey]: dict1[sharedkey]} 
     print resultDict 
0
#!/usr/bin/env python 

list1 = [ 

    {'X1': 'AAA1', 'X2': 'BAA5'}, 
    {'AB1': 'AAA1', 'CB2': 'BAA5'}, 
    {'B1': 'AAA1', 'C2': 'BAA5'} 

    ] 


dict1 = { 
    'X1': set(['B00001','B00002','B00003']), 
    'AB1': set(['B00001','B00002','B00003']) 
}  


g = (k.iteritems() for k in list1) 
ite = ((a,b) for i in g for a,b in i if dict1.has_key(a)) 

d = dict(ite)    
print d   
관련 문제