有没有办法在O(1)时间内使用其中一个键获取值

时间:2017-03-09 14:48:50

标签: python dictionary data-modeling

我正在为应用程序建模数据,并决定选择字典作为我的数据结构。但是数据中的每一行都有多个键。所以我创建了一个字典,其中每行都有多个键映射,如:

>>> multiKeyDict = {}
>>> multiKeyDict[('key1','key2','key3')] = 'value1'
>>> multiKeyDict.get(('key1','key2','key3'))
'value1'

现在我必须在O(1)时间内使用key1检索所有值。从我的研究中我知道我可以做到:

我也对任何更好的数据结构开放,而不是使用字典。

2 个答案:

答案 0 :(得分:1)

您没有多个密钥。就Python字典而言,只有一个键,一个元组对象。除了O(N)线性时间之外,你不能搜索元组的成分。

如果您的密钥是唯一的,只需单独添加每个密钥:

multiKeyDict['key1'] = multiKeyDict['key2'] = multiKeyDict['key3'] = 'value1'

现在你有3个键都引用一个值。这里不重复值对象,只有对它的引用。

您找到的multi_key_dict包使用中间映射将给定的组成键映射到组合键,然后映射到该值。这也为您提供O(1)搜索,具有相同的限制,即每个组成键必须是唯一的。

如果您的密钥唯一,那么您需要将每个密钥映射到另一个容器,然后容纳值,例如一组:

for key in ('key1', 'key2', 'key3):
    multiKeyDict.setdefault(key, set()).add(value)

现在查找一个键可以获得该键引用的所有值的集合。

如果您还需要能够组合键,则可以使用这些组合添加其他参考。键值配对相对便宜,它只是参考。键和值对象本身不重复。

答案 1 :(得分:0)

另一种可能性是为共享关键组件的行对象列表建立索引。如果共享任何特定键值的行数很小,这将非常有效。 (假设行对象具有以row.key1row.key2等方式访问的密钥,这不是一个非常相关的细节。未经测试的代码:

index = {}
for row in rows:
    index.setdefault( row.key1, []).append(row)
    index.setdefault( row.key2, []).append(row)
    index.setdefault( row.key3, []).append(row)

然后查找匹配的行,例如key2key3

candidates = index[ key2] 
if len( index[key3]) < len(candidates): 
    candidates = index[key3] # use key3 if it offers a better distribution
results = []
for cand in candidates:
    if cand.key2 == key2 and cand.key3 == key3: # full test is necessary!
        results.append( cand)