如何分配3个数据的集合

时间:2012-10-15 10:21:35

标签: python python-2.7

我有几十个元组,每个元组包含2个字符串和1个整数。实施例:(str, str, int)。 所有这些元组都在一个列表中(如下例所示)。 每个元组都是唯一的,每个元组的字符串和整数也是唯一的。

例:

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

我想要的是,使用像字典这样的数据结构,并检索我传递的 <3>中的任何一个的整个元组。

  

例:

     

对于值'a' - &gt;得到整个元组:('a', 'aA', 53)

     

对于值'cc' - &gt;得到整个元组:('c', 'cc', 234)

     

对于值'76' - &gt;得到整个元组:('d', 'de', 76)

到目前为止,我已经完成了: 创建一个简单的函数来遍历元组列表,遍历每个元组及其所有3个值以找到匹配项,如果匹配则返回元组,如果不返回False。

这听起来很慢,似乎是完成这项任务的非常错误的方式。

  1. 实现这一目标的正确方法是什么?
  2. 我应该创建3个词典并将它们相互链接吗?

3 个答案:

答案 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]

您可以将其全部捆绑在一个类中,在您添加或删除元素时,索引会保持最新。

答案 1 :(得分: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”应该返回什么
[('a','aA', 53),
('b','bb', 21),
('a','ca', 234),
..]

答案 2 :(得分:1)

要保持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)