Python线性搜索提高效率

时间:2015-10-20 13:11:51

标签: python algorithm csv binary-search linear-search

我对Linear Searching中的Python提出了疑问。说我有

的基本代码
for l in lines:
  for f in search_data:
     if my_search_function(l[1],[f[0],f[2]]):
        print "Found it!"
        break

我们希望在search_data中确定存储在l[1]中的值的位置。说my_search_function()看起来像这样:

def my_search_function(search_key, search_values):
   for s in search_values:
      if search_key in s:
         return True
    return False

有没有办法提高处理速度? Binary搜索在这种情况下不起作用,因为行和search_data是多维列表,我需要保留索引。我尝试了一种从外到底的方式,即

for line in lines:
    negative_index = -1
    positive_index = 0
    middle_element = len(search_data) /2 if len(search_data) %2 == 0 else (len(search_data)-1) /2
    found = False

    while positive_index < middle_element:
        # print str(positive_index)+","+str(negative_index)
        if my_search_function(line[1], [search_data[positive_index][0],search_data[negative_index][0]]):
            print "Found it!"
            break
        positive_index = positive_index +1
        negative_index = negative_index -1

但是,我没有看到任何速度增加。有没有人有更好的方法?我正在寻求将处理速度降低一半,因为我正在使用大量CSV并且一个文件的处理时间是&gt; 00:15 这是不可接受的,因为我正在处理30多个文件的批次。基本上我搜索的数据基本上是SKU。 lines[0]的值可能类似AS123JK,该值的有效匹配可能为AS123。所以HashMap在这里不起作用,除非有一种方法可以在HashMap查找中进行部分匹配,这不会要求我分解像['AS123', 'AS123J', 'AS123JK']这样的值,这在这种情况下并不理想。谢谢!

3 个答案:

答案 0 :(得分:1)

  

二进制搜索在这种情况下不起作用,因为lines和search_data是多维列表,我需要保留索引。

无论如何,在bisect module的帮助下,将字符串(以及对原始数据结构的一些引用)提取到平面列表,对其进行排序并对其执行快速二进制搜索可能是值得的。

或者,除了大量搜索之外,还要对所有搜索键的组合列表进行排序,并并行遍历两个列表,以查找匹配项。 (以与合并排序中的合并步骤类似的方式继续进行,而不实际输出合并列表)

代码说明第二种方法:

lines = ['AS12', 'AS123', 'AS123J', 'AS123JK','AS124']
search_keys = ['AS123', 'AS125']

try:
    iter_keys = iter(sorted(search_keys))
    key = next(iter_keys)
    for line in sorted(lines):
        if line.startswith(key):
            print('Line {} matches {}'.format(line, key))
        else:
            while key < line[:len(key)]:
                key = next(iter_keys)
except StopIteration: # all keys processed
    pass

答案 1 :(得分:0)

取决于问题的细节。

例如,如果搜索完整的单词,可以在可搜索的元素上创建哈希表,最终的搜索将是一个简单的查找。

填充哈希表是伪线性的。

答案 2 :(得分:0)

最终,我通过使用带有lambda作为关键参数的sorted()函数进行排序来分解并在我的多维列表上实现二进制搜索。这是我提出的第一个密码。它不是100%有效率,但它是我们所处的巨大改进

def binary_search(master_row, source_data,master_search_index, source_search_index):
    lower_bound = 0
    upper_bound = len(source_data) - 1
    found = False
    while lower_bound <= upper_bound and not found:
        middle_pos = (lower_bound + upper_bound) // 2

        if source_data[middle_pos][source_search_index] < master_row[master_search_index]:

            if search([source_data[middle_pos][source_search_index]],[master_row[master_search_index]]):
                return {"result": True, "index": middle_pos}
                break
            lower_bound = middle_pos + 1

        elif source_data[middle_pos][source_search_index] > master_row[master_search_index] :

            if search([master_row[master_search_index]],[source_data[middle_pos][source_search_index]]):
                return {"result": True, "index": middle_pos}
                break
            upper_bound = middle_pos - 1
        else:

            if len(source_data[middle_pos][source_search_index]) > 5:

                return {"result": True, "index": middle_pos}
            else:
                break

然后我们实际进行二元搜索调用

#where master_copy is the first multidimensional list, data_copy is the second
#the search columns are the columns we want to search against
for line in master_copy:
    for m in master_search_columns:
        found = False
        for d in data_search_columns:
            data_copy = sorted(data_copy, key=lambda x: x[d], reverse=False)
            results = binary_search(line, data_copy,m, d)
            found = results["result"]
            if found:
                line = update_row(line, data_copy[results["index"]], column_mapping)
                found_count = found_count +1
                break
        if found:
            break

这是排序多维列表Python Sort Multidimensional Array Based on 2nd Element of Subarray

的信息