我对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']
这样的值,这在这种情况下并不理想。谢谢!
答案 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
的信息