2012-10-15 69 views
0

我有幾十個元組,每個元組包含2個字符串和1個整數。例如:(str, str, int)。 所有這些元組都在列表中(下例)。 每個元組都是唯一的,每個元組的字符串和整數也是唯一的。如何分配3個數據集合

例:

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

我要的是,使用這種數據結構就像一本字典和檢索的任何3個值我傳遞的一個整個數組。

例:

對於價值'a' - >獲得的整個元組:('a', 'aA', 53)

對於價值'cc' - >獲得的整個元組:('c', 'cc', 234)

對於價值'76' - >得到整個元組:('d', 'de', 76)

S o我已經完成了: 創建一個簡單的函數來遍歷元組列表,遍歷每個元組及其所有3個值來查找匹配,並且如果有匹配返回元組,則返回False。

這聽起來很慢,似乎是做這個任務的錯誤方式。

  1. 什麼是正確的方法來實現這一目標?
  2. 我應該創建3個詞典並將它們彼此鏈接嗎?
+1

你是怎麼得到'''''(''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) 

雖然,你沒有指定,如果一個元素是不是在一個元組更要發生什麼。 什麼應返回的

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

「a」的列表要保持O(1)擡頭可以創建這樣一個字典從這些元組:

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)