优化搜索以查找列表中的下一个匹配值

时间:2013-04-16 21:34:25

标签: python bigdata

我有一个程序遍历列表,每个对象找到具有匹配值的下一个实例。当它这样做时,它打印出每个对象的位置。该程序运行完美,但我遇到的麻烦是当我运行大量数据(列表中约6,000,000个对象)时,它将花费太长时间。如果有人能够提供有关如何提高流程效率的见解,我将非常感激。

def search(list):
    original = list
    matchedvalues = []
    count = 0
    for x in original:
        targetValue = x.getValue()
        count = count + 1
        copy = original[count:]
        for y in copy:
             if (targetValue == y.getValue):
                 print (str(x.getLocation) + (,) + str(y.getLocation))
                 break

2 个答案:

答案 0 :(得分:2)

也许你可以创建一个包含与每个项目对应的索引列表的字典,如下所示:

values = [1,2,3,1,2,3,4]

from collections import defaultdict

def get_matches(x):
    my_dict = defaultdict(list)
    for ind, ele in enumerate(x):
        my_dict[ele].append(ind)
    return my_dict

结果:

>>> get_matches(values)
defaultdict(<type 'list'>, {1: [0, 3], 2: [1, 4], 3: [2, 5], 4: [6]})

编辑:

我添加了这部分内容,以防它有用:

values = [1,1,1,1,2,2,3,4,5,3]

def get_next_item_ind(x, ind):
    my_dict = get_matches(x)
    indexes = my_dict[x[ind]]
    temp_ind = indexes.index(ind)
    if len(indexes) > temp_ind + 1:
        return(indexes)[temp_ind + 1]
    return None

结果:

>>> get_next_item_ind(values, 0)
1
>>> get_next_item_ind(values, 1)
2
>>> get_next_item_ind(values, 2)
3
>>> get_next_item_ind(values, 3)
>>> get_next_item_ind(values, 4)
5
>>> get_next_item_ind(values, 5)
>>> get_next_item_ind(values, 6)
9
>>> get_next_item_ind(values, 7)
>>> get_next_item_ind(values, 8)

答案 1 :(得分:1)

有几种方法可以通过最大限度地减少额外的内存使用来提高搜索效率(特别是当您的数据很大时)。

  • 您可以直接在传递的列表中操作,也不需要复制它,这样您就不需要:original = listcopy = original[count:]
  • 您可以使用原始列表的切片进行测试,并enumerate(p)遍历这些切片。您不需要额外的变量count,而enumerate(p)在Python中是有效的

重新实施,这将成为:

def search(p):
    # iterate over p
    for i, value in enumerate(p):

        # if value occurs more than once, print locations
        # do not re-test values that have already been tested (if value not in p[:i])
        if value not in p[:i] and value in p[(i + 1):]:
            print(e, ':', i, p[(i + 1):].index(e))

v = [1,2,3,1,2,3,4]

search(v)

1 : 0 2
2 : 1 2
3 : 2 2

以这种方式实现它只会打印重复值的值/位置(我认为这是您在原始实现中的意图)。

其他考虑因素:

  • 超过2次出现的值:如果值在列表中重复多次,那么您可能希望实现一个函数以递归方式遍历列表。事实上,这个问题没有解决这个问题 - 而且可能在你的情况下不需要这样做。

  • 使用字典:我完全赞同上面的Akavall,字典是在Python中查找值的好方法 - 特别是如果你需要在程序中稍后再次查找值。如果在最初创建列表时构造字典而不是列表,这将最有效。但是如果你只是这样做一次,那么构建字典和查询就会花费你更多的时间,而不是像上面所描述的那样简单地遍历列表。

希望这有帮助!