python中的快速数据比较

时间:2011-10-31 03:05:12

标签: python list dictionary comparison

我希望以2种不同长度的字典形式比较大量数据。  (编辑)

post = {0: [0.96180319786071777, 0.37529754638671875], 
        10: [0.20612385869026184, 0.17849941551685333],
        20: [0.20612400770187378, 0.17510984838008881],...}

pre = {0: [0.96180319786071777, 0.37529754638671875],
       1: [0.20612385869026184, 0.17849941551685333],
       2: [0.20612400770187378, 0.17510984838008881],
       5065: [0.80861318111419678, 0.76381617784500122],...}

我们需要得到的答案是5065:[0.80861318111419678,0.76381617784500122]。这是基于我们只是比较价值而不是指数的事实。

我只使用此键值对来记住数据序列。如果需要,可以用列表/集替换数据类型。我需要找出关键:与字典不相同的元素的值(索引和值)对。

我使用的代码非常简单..

new = {}
found = []

for i in range(0, len(post)): 
    found= []
    for j in range(0, len(pre)): 
        if post[i] not in pre.values():
            if post[i] not in new:
                new[i] = post[i]
                found.append(j)             
                break
    if found:
        for f in found: pre.pop(f)

new {}包含我需要的元素。 我面临的问题是这个过程太慢了。处理有时需要一个多小时。有时数据可能会大得多。我需要它更快。

有没有一种有效的方法来实现我想要实现的目标?除非绝对必要,否则除了那些与python 2.5(64位)捆绑在一起的外部软件包之外我不想依赖外部软件包。

谢谢大家。

2 个答案:

答案 0 :(得分:5)

这基本上是set的设计目标(计算项目集的差异)。唯一的问题是你放入set的东西需要是可以清洗的,而list则不是。但是,tuple是,所以如果你转换成那个,你可以把它们放到一个集合中:

post_set = set(tuple(x) for x in post.itervalues())
pre_set = set(tuple(x) for x in pre.itervalues())

items_in_only_one_set = post_set ^ pre_set

有关set s的更多信息:http://docs.python.org/library/stdtypes.html#set

要在计算差异后获取原始索引,您可能需要的是生成反向查找表:

post_indices = dict((tuple(v),k) for k,v in post.iteritems())
pre_indices = dict((tuple(v),k) for k,v in pre.iteritems())

然后你可以通过字典获取一个给定的元组并查找其索引:

index = post_indices.get(a_tuple, pre_indices.get(a_tuple))

答案 1 :(得分:1)

您的问题可能是嵌套for循环与range()的使用相结合,每次创建一个新的list可能会很慢。您可能会通过直接迭代prepost获得一些自动加速,并避免以嵌套方式执行此操作。

post = {0: [0.96180319786071777, 0.37529754638671875],
       10: [0.20612385869026184, 0.17849941551685333],
       20: [0.20612400770187378, 0.17510984838008881]}

pre = {0: [0.96180319786071777, 0.37529754638671875],
       1: [0.20612385869026184, 0.17849941551685333],
       2: [0.20612400770187378, 0.17510984838008881],
    5065: [0.80861318111419678, 0.76381617784500122]}

'''Create sets of values, independent of dict key for O(1) lookup'''
post_set=set(map(tuple, post.values()))
pre_set=set(map(tuple, pre.values()))

'''Iterate through each structure only once, filtering items that are found in
   the sets we created earlier, updating new_diff'''
from itertools import ifilterfalse

new_diff=dict(ifilterfalse(lambda x: tuple(x[1]) in pre_set, post.items()))
new_diff.update(ifilterfalse(lambda x: tuple(x[1]) in post_set, pre.items()))

new_diff现在为dict,因此在postpre中找不到每个值,并保留原始索引。

>>> print new_diff
{5065: [0.80861318111419678, 0.76381617784500122]}