使用列表和词典存储临时信息

时间:2010-09-28 20:14:49

标签: python

我会有很多类似参数的类似对象。对象参数的示例如下:

名称,布尔值,数字和列表。

名称必须是所有对象中的唯一值,而boolean,number和list参数的值不能。

我可以将数据存储为字典列表。像那样:

list = [
  {'name':'a', 'bool':true, 'number':123, 'list':[1, 2, 3]},
  {'name':'b', 'bool':false, 'number':143, 'list':[1, 3, 5]},
  {'name':'c', 'bool':false, 'number':123, 'list':[1, 4, 5, 18]},
]

在我在该列表中创建另一个字典之前,检查字典列表中是否存在唯一名称的最快方法是什么?我是否必须遍历列表并检查list [i] [name]的值是什么?假设不同的类似列表可以在不同的线程/任务中同时处理,并且它们的大小可以是每列表100到100 000个字典之间的任何值,那么保存和处理该信息的最快和最少的内存保留是什么。我应该将这些列表存储在数据库而不是内存中吗?

我理解也许我不应该在项目工作之前考虑优化(存储信息和线程),所以请首先回答唯一的名称查找问题:)

谢谢, 艾伦

5 个答案:

答案 0 :(得分:6)

如果名称是每个内部数据的实际(唯一)标识符,您也可以使用字典作为外部数据:

data = {
  'a' : { 'bool':true, 'number':123, 'list':[1, 2, 3] },
  'b' : { 'bool':false, 'number':143, 'list':[1, 3, 5] },
  'c' : { 'bool':false, 'number':123, 'list':[1, 4, 5, 18] },
}

然后您可以轻松检查密钥是否存在。

顺便说一下。不要将变量命名为listdict,因为这会覆盖内置对象。

答案 1 :(得分:1)

一旦你开始使用dict而不是列表,执行所需检查的最快方法是:

if 'newkey' not in items:
    # create a new record

因为你希望能够从多个线程访问这些记录,所以我会保留一组锁。顺便说一句,这是你在开始时设计的那种东西,因为它是应用程序设计的一部分,优化。

class DictLock(dict):
    def __init__(self):
        self._lock = threading.Lock()

    def __getitem__(self, key):
        # lock to prevent two threads trying to create the same
        # entry at the same time. Then they would get different locks and
        # both think that they could access the key guarded by that lock
        with self._lock:
            if key not in self.iterkeys():
                self[key] = threading.Lock()
            return super(DictLock, self).__getitem__(key)

现在,如果你想修改你的物品,你可以使用锁来保证它的安全。

locks = DictLock()

with locks['a']:
    # modify a.

或插入新元素

with locks['z']:
    #we are now the only ones (playing by the rules) accessing the 'z' key
    items['z'] = create_new_item()

答案 2 :(得分:0)

将对象存储在名称为键的字典中:

objects = {'a' : {'bool':true, 'number':123, 'list':[1, 2, 3]},
           'b' : {'bool':false, 'number':143, 'list':[1, 3, 5]},
           'c' : {'bool':false, 'number':123, 'list':[1, 4, 5, 18]}}

这样可以确保名称是唯一的,因为字典中的所有键都是唯一的。检查是字典中的名称也很容易:

name in objects

答案 3 :(得分:0)

你想要的是一个“侵入式”字典 - 在内部寻找键值的东西。不幸的是,我不知道Python中的任何实现。 Boost的multi_index非常接近。

答案 4 :(得分:0)

如果您不想更改所拥有的数据结构,则可以使用以下内容。否则,戳的答案是要走的路。

>>> my_list = [
...   {'name':'a', 'bool':True, 'number':123, 'list':[1, 2, 3]},
...   {'name':'b', 'bool':False, 'number':143, 'list':[1, 3, 5]},
...   {'name':'c', 'bool':False, 'number':123, 'list':[1, 4, 5, 18]},
... ]
>>> def is_present(data, name):
...     return any(name == d["name"] for d in data)
... 
>>> is_present(my_list, "a")
True
>>> is_present(my_list, "b")
True
>>> is_present(my_list, "c")
True
>>> is_present(my_list, "d")
False

如果您传递any一个iterable,如果其中任何一个元素为True,则返回True。

(name == d["name"] for d in data)创建一个生成器。每当有人(在这种情况下,any)请求下一个元素时,它会通过从d获取下一个元素data并通过表达式{{1}对其进行转换来实现。 }。由于生成器是惰性的,即在请求下一个元素时完成转换,因此应使用相对较少的内存(并且无论列表的大小如何,都应使用相同数量的内存)。