0

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

前任。:

[('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)

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

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

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

3 回答 3

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]

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

于 2012-10-15T10:28:05.987 回答
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)

Though, you didn't specify, what should happen if one element is in more than in one tuple. What should be return for 'a' in list of

[('a','aA', 53),
('b','bb', 21),
('a','ca', 234),
..]
于 2012-10-15T10:28:12.977 回答
1

To keep a O(1) look up you can create a dictionary like this from those tuples:

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)}

now searching any item becomes easy:

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)
于 2012-10-15T10:33:52.727 回答