2012-10-15 2 views
0

두 개의 문자열과 1 개의 정수가 포함 된 수십 개의 튜플이 있습니다. 예 : (str, str, int). 이러한 모든 튜플은 목록에 있습니다 (아래 예 참조). 각 튜플은 고유하며 각 튜플의 문자열과 정수도 고유합니다.3 개의 데이터 집합을 할당하는 방법

예 : 무엇 내가 원하는

[('a','aA', 53), 
('b','bb', 21), 
('c','cc', 234), 
('d','de', 76), 
..] 

는 사전처럼이 데이터 구조를 사용하고 난 패스 3 개 값의 하나의에 대한 전체 튜플을 검색 할 수 있습니다.

예 : 값

'a' ->의 전체 튜플 수 : 값 'cc'를 들어 ('a', 'aA', 53)

을 -> 전체 튜플을 얻을 : ('c', 'cc', 234)'76'를 들어

-> 전체 튜플을 얻으십시오 : ('d', 'de', 76)

멀리까지 내가 수행 한 것 : 튜플 목록을 반복하는 간단한 함수를 생성하여 각 튜플과 그 모든 3 개의 값을 검색하여 일치하는 것을 찾고, 일치하는 것이 있으면 튜플을 반환하고 그렇지 않으면 False를 반환한다.

이 소리는 느리고 들리며이 작업을 수행하는 아주 잘못된 방법 인 것 같습니다.

  1. 이것을 달성하는 올바른 방법은 무엇입니까?
  2. 3 개의 사전을 만들고 서로 링크해야합니까?
+1

어떻게''4 ''에'('d', 'de', 76)를 얻었습니까? –

+0

Ashwini; 너는하지 않는다. 그것은 물론 어리석은 오타였습니다. – Phil

+0

여러 경기를 어떻게 처리합니까? –

답변

1
당신은 내용으로 요소를 찾는 수 있도록 사전을 사용하여 별도의 인덱스를 생성해야 할 것

:

지금
from collections import defaultdict 

index_on_1 = defaultdict(list) 
index_on_2 = defaultdict(list) 
index_on_3 = defaultdict(list) 

for i, (val1, val2, val3) in enumerate(yourstructure): 
    index_on_1[val1].append(i) 
    index_on_2[val2].append(i) 
    index_on_3[val3].append(i) 

당신은 문자열에 인덱스를 찾아 볼 수 있습니다 :

from itertools import chain 

def lookup(entry): 
    if isinstance(entry, str): 
     entries = chain(index_on_1.get(entry, []), index_on_2.get(entry, [])) 
     return [yourstructure[i] for i in entries] 
    else: 
     return [yourstructure[i] for i in index_on_3.get(entry, [])] 

참고이 있음 항목이 여러 튜플과 일치 할 수 있으므로 항상 목록을 반환합니다. 조회가 문자열 인 경우 첫 번째 두 개의 색인 만 사용하고 그렇지 않으면 세 번째 색인 만 사용합니다.

또는 항목 유형에 대해 상관하지 않는다 더 일반적인 솔루션은 3 개 별도의 변수 대신, 인덱스의 목록을 작성하는 것입니다 : 조회와

indexes = [defaultdict(list) for _ in range(3)] 

for i, values in enumerate(yourstructure): 
    for index, val in zip(indexes, values): 
     index[val].append(i) 

되고 :

def lookup(entry): 
    entries = chain(*[index.get(entry, []) for index in indexes]) 
    return [yourstructure[i] for i in entries] 

요소를 추가하거나 제거 할 때 색인이 최신으로 유지되는 클래스에이 모든 것을 묶을 수 있습니다.

+0

Martijn, 시간과 설명에 감사드립니다. 나는 당신에게서 많은 것을 배웁니다. 나는 당신의 첫 번째 접근법이 컴퓨터 프로그래밍에서 가장 합리적인 방법이라고 생각하여 색인을 만들 것입니다. 그것은 더 의미가 있습니다. 리소스 사용량을 낮게 유지하기 위해 필자는 코드를 뒤섞어서는 안됩니다. 고마워요! – Phil

1

쉬운, 단순한 방법은 다음과 같습니다

>>> your_list 
[('a', 'aA', 53), ('b', 'bb', 21), ('c', 'cc', 234), ('d', 'de', 76)] 
>>> def get_tuple(list_of_tuples, elem): 
...  for item in list_of_tuples: 
...    if elem in item: 
...      return item 
...  return False 
... 
>>> get_tuple(your_list, 'a') 
('a', 'aA', 53) 
>>> get_tuple(your_list, 'cc') 
('c', 'cc', 234) 

비록, 당신은 하나 개의 요소가 하나의 튜플보다 더에있는 경우 어떤 일이 일어날해야 지정하지 않았습니다. O(1)는 당신이 그 튜플에서이 같은 사전을 만들 수 있습니다 찾아 유지하는

[('a','aA', 53), 
('b','bb', 21), 
('a','ca', 234), 
..] 
1

의 'A'의 목록을 반환해야하는 것 : 지금 모든 항목을 검색

In [20]: lis=[('a','aA', 53), 
    ....: ('b','bb', 21), 
    ....: ('c','cc', 234), 
    ....: ('d','de', 76)] 

In [22]: dic=dict((y,x) for x in lis for y in x) 

In [23]: dic 

Out[23]: 
{21: ('b', 'bb', 21), 
53: ('a', 'aA', 53), 
76: ('d', 'de', 76), 
234: ('c', 'cc', 234), 
'a': ('a', 'aA', 53), 
'aA': ('a', 'aA', 53), 
'b': ('b', 'bb', 21), 
'bb': ('b', 'bb', 21), 
'c': ('c', 'cc', 234), 
'cc': ('c', 'cc', 234), 
'd': ('d', 'de', 76), 
'de': ('d', 'de', 76)} 

쉽게된다 :

In [24]: dic.get('a','not found') 
Out[24]: ('a', 'aA', 53) 

In [25]: dic.get('aA','not found') 
Out[25]: ('a', 'aA', 53) 

In [26]: dic.get('21','not found') 
Out[26]: 'not found' 

In [27]: dic.get(21,'not found') 
Out[27]: ('b', 'bb', 21) 
관련 문제