我会有很多类似参数的类似对象。对象参数的示例如下:
名称,布尔值,数字和列表。
名称必须是所有对象中的唯一值,而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个字典之间的任何值,那么保存和处理该信息的最快和最少的内存保留是什么。我应该将这些列表存储在数据库而不是内存中吗?
我理解也许我不应该在项目工作之前考虑优化(存储信息和线程),所以请首先回答唯一的名称查找问题:)
谢谢, 艾伦
答案 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] },
}
然后您可以轻松检查密钥是否存在。
顺便说一下。不要将变量命名为list
或dict
,因为这会覆盖内置对象。
答案 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}对其进行转换来实现。 }。由于生成器是惰性的,即在请求下一个元素时完成转换,因此应使用相对较少的内存(并且无论列表的大小如何,都应使用相同数量的内存)。