O(1)查找dict中的单个元组元素?

时间:2014-12-02 08:58:46

标签: python dictionary data-structures tuples

我有一个结构,类似于以元组为键的dict,除了你可以查找只有一个元组元素的条目。

e.g。 (类似于此。不是真正的Python代码,只是一个想法)

>>> d[(100, "apple")] = 5.0 # putting entry into dict
>>> d[(100, "pear")] = 10.0 # putting entry into dict
>>> d[(200, "pear")] = 10.0 # putting entry into dict
>>> d[100] # O(1) lookup
[("apple", 5.0), ("pear", 10.0)]
>>> d["pear"] # O(1) lookup
[(100, 10.0), (200, 10.0)]

您目前无法使用defaultdict()执行此操作。在Python中执行此操作的最佳方法是什么,或者使用最佳数据结构?我希望查找为O(1),就像它是dict一样。

在这种情况下,元组元素既不是唯一的,也不是值。

我在考虑:

  • 嵌套词典
  • 两句话?
  • 某些类似数据库的结构

3 个答案:

答案 0 :(得分:1)

考虑类似的事情:

class MyDict(object):

    def __init__(self):
        self._data = {}

    def __setitem__(self, key, val):
        self._data[key] = val
        if key[0] not in self._data:
            self._data[key[0]] = {}
        self._data[key[0]][key[1]] = val

    def __getitem__(self, key):
        return self._data[key]

这允许在O(1)中通过元组或其第一个元素进行查找。然后,您可以为key[1]实现相同的功能。使用词典字典可以随后查找键O(1)的其他部分。使用中:

>>> d = MyDict()
>>> d[100, "apple"] = 5.0
>>> d[100, "pear"] = 10.0
>>> print d[100]
{'pear': 10.0, 'apple': 5.0}
>>> print d._data
{(100, 'apple'): 5.0, (100, 'pear'): 10.0, 100: {'pear': 10.0, 'apple': 5.0}}

请注意,这假设每个组合key[0], key[1]只有一个val

参见例如How to "perfectly" override a dict?制作自定义词典。

答案 1 :(得分:0)

有两种常见的可能性。

  • 对于较小的词典:覆盖__getitem__的{​​{1}}和__setitem__以实现您的要求。关于这一点,有几个问题。
  • 对于较大的词典:使用具有可用查询语言的数据库。例如:内存中的sqlite,但它取决于持久性和API要求。

回答dict示例

的问题
sqlite3

您还可以使用对象关系映射器或其他数据库(如键值存储),它们可能更符合您的需求。

使用数据库确实不比字典查找快。但是你有一些优点,如持久性和查询API。如果数据库符合您的需求,我不会优化速度到早期。它取决于你。

答案 2 :(得分:-1)

为什么不使用namedtuple之类的

>>>>from collections import namedtuple  
>>>>Fruit = namedtuple("Fruit", ["name", "count"])  
>>>>f1 = Fruit(name="apple", count=100)  
>>>>f2 = Fruit(name="pear", count=100)  
>>>>print f1  
Fruit(name='apple', count=100)  
>>>>print f2  
Fruit(name='pear', count=100)  
>>>>f1.name  
'apple'  
>>>>f1.count
100
>>>>f2.name  
'pear'  

现在使用fruitcount字典作为

>>>>fruitcount = {f1: 5.0}
>>>>fruitcount = {f2: 10.0}
>>>>fruitcount[f1]
5.0
>>>>fruitcount[f2]
10.0

有关详细信息,请参阅此处:python-docs