2013-02-15 16 views
0

查一查字典蟒值我有了钥匙Unix纪元时间戳,像这样一个字典:通过表达

lookup_dict = { 
    1357899: {} #some dict of data 
    1357910: {} #some other dict of data 
} 

除此之外,你知道,参赛的数以百万计和数以百万计。我想重复这个词典,一遍又一遍。理想情况下,我很乐意能写的东西像我可以在R,像:

lookup_value = 1357900 
dict_subset = lookup_dict[key >= lookup_value] 
# dict_subset now contains {1357910: {}} 

但我承认,我找不到任何实际证明,这是Python的东西,而不必能做的,一个方式或其他,遍历每一行。如果我正确地理解了Python(并且我可能不),key in dict表格的密钥查找使用二进制搜索,因此速度非常快;任何方式来执行二进制搜索,在字典键?

+0

密钥是唯一的,并有一个相应的值。他们要么在字典中,要么不在字典中。我不明白这个问题。 – NullUserException 2013-02-15 00:48:49

+2

键被散列 - 不在btrees中。所以,也许你想看看'bisect'模块将列表作为关键字,并将字典列表作为相应的值 - 并在找到合适的索引后使用切片.... – 2013-02-15 00:52:04

+0

@JonClements:这是有效的,但我建议使用包装'bisect'的两个'sortedlist'食谱中的一个(或者可能不是,就像'blist'中的那个'),因为基于“基于二分法”代码很难阅读,并且容易出错。 – abarnert 2013-02-15 01:09:14

回答

2

要做到这一点而不进行迭代,您将需要排序顺序的键。那么你只需要对第一个>= lookup_value进行二分搜索,而不是检查每个搜索的>= lookup_value

如果你愿意使用第三方库,那里有很多。前两个想到的是bintrees(使用红黑树,如C++,Java等)和blist(使用B +树)。例如,对于bintrees,它是如此简单:

dict_subset = lookup_dict[lookup_value:] 

,这将被视为有效,你倒是希望,基本上,它增加了使用该子集的不惜一切代价的上方设置了一个O(log N)搜索。 (当然,通常你想对这个子集做的事情是迭代整个事情,无论如何它最终会成为O(N)......但是也许你正在做一些不同的事情,或者这个子集只有1000000个中的10个键。)

当然有一个权衡。随机访问基于树的映射是O(log N)而不是“通常O(1)”。此外,您的密钥显然需要完全订购,而不是可哈希(并且很难自动检测并提出好的错误消息)。

如果你想自己建立这个,你可以。你甚至不一定需要一棵树;只是排序list的键旁边dict。正如JonClements建议的那样,您可以使用stdlib中的bisect模块来维护list。您可能想要包装bisect以创建一个排序列表对象,或者更好的方法是获取ActiveState或PyPI上的一个配方来为您做。然后,您可以将排序列表和dict组合到一个对象中,这样您就不会意外更新其中一个而不更新其他对象。如果你愿意的话,你可以将接口扩展到bintrees

+0

废话。谢谢!这......非常好,正是我想知道的。正如你正确地认识到的那样(尽管我,呃,在我的问题中可能没有说清楚),我们的目标是取一组〜200M行,并在单个数字中包含一个子集,查找结果是.. 。 复杂。但它使我非常乐意使用第三方库;我会看看'bintrees'。非常感谢! – Gastove 2013-02-16 01:41:08

0

使用下面的代码将制定出

some_time_to_filter_for = # blah unix time 
# Create a new sub-dictionary 
sub_dict = {key: val for key, val in lookup_dict.items() 
      if key >= some_time_to_filter_for} 

基本上我们只是通过在你的字典里所有键进行迭代,并给出一个时间过滤掉了,我们要把一切都大于或等于键值并将它们放入我们的新词典中

+0

问题是“如何不迭代”。另外,不要使用'items()'。 – wRAR 2013-02-15 01:02:15

+1

'items()'在python 3上是可以的 – wim 2013-02-15 01:07:43

+0

@wim我知道,但我仍然认为Python 2的所有用法应该明确地标记为这样。 – wRAR 2013-02-15 01:29:12