【发布时间】:2016-06-20 23:54:50
【问题描述】:
让我坦率地说,我编写代码是为了好玩,这是我过去几天在业余时间一直在进行的代码挑战。挑战在于我得到一堆由空格(文档)分隔的单词,然后是列表中的几个搜索词。我必须在文档中找到最接近这些 searchTerms 的位置。基本上,找到包含所有 searchTerms 的文档的最小子集并输出该子集。到目前为止,我的功能似乎在我的系统上运行。但是,当我上传时,我被告知我的算法执行时间太长。我的想法是在文档中找到 searchTerm 的每个实例,然后针对它运行 itertools.product()。然后我测试每一个,根据索引值确定哪一个是最短的。这是我目前所拥有的:
def answer(document, searchTerms):
from itertools import product
#build a list of the input document
document = document.split()
index = []
#find all indexes for the searchTerms and build a list of lists
for w in searchTerms:
index.append([i for i,x in enumerate(document) if x == w])
#build iterator of all possible combinations of indexes for each of the searchTerms
combinations = product(*index)
#recover memory
del index
#build tuple of minimum distance between all search terms
shortest = min(((max(x) - min(x),x) for x in combinations),key=lambda x: x[0])
return (' '.join(document[min(shortest[1]):max(shortest[1])+1]))
我尝试使用多处理来加速我的代码部分,但还没有完全掌握正确的语法。例如:
from multiprocessing import Pool
p = Pool(processes=2)
shortest = p.map(min_max,combinations)
def min_max(combinations):
return min(((max(x) - min(x),x) for x in combinations))
结果:
Traceback (most recent call last):
File "./searchTerms2.py", line 65, in <module>
print (answer(document,searchTerms))
File "./searchTerms2.py", line 45, in answer
shortest = p.map(min_max,combinations)
File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map
return self.map_async(func, iterable, chunksize).get()
File "/usr/lib/python2.7/multiprocessing/pool.py", line 567, in get
raise self._value
TypeError: 'int' object is not iterable
任何指针将不胜感激。有没有更好的方法来解决这个问题?在哪些方面我可以提高效率?
--编辑-- 问题进一步解释:
document = 'this is a song that never ends it goes on and on my friend some people started singing it not knowing what it was and they will continue singing it forever just because this is the song'
searchTerms = ['this', 'goes','on']
应该导致:
'this is a song that never ends it goes on'
这适用于我当前的算法,但如果给定更大的文档和 searchTerms,则速度不够快。我希望这更清楚...
我一直在为我的代码计时,看来我最大的性能影响来自:
shortest = min(((max(x) - min(x),x) for x in combinations),key=lambda x: x[0])
随着我增加“文档”中的字数并在“搜索词”中添加额外的搜索词,我看到该行的性能受到很大影响。其他一切都与我能说的相差无几..
【问题讨论】:
-
如果您的目标是速度,那么任何带有
#recover memory的行都可能不存在,除非您正在处理可能会将您送入虚拟内存的多 GB 数组。 -
不是为每个搜索词执行
index.append([i for i,x in enumerate(document) if x == w]),而是执行index.append([i for i,x in enumerate(document) if x in searchTerms])。此外,将searchTerms转换为set以加快查找速度。 -
我会把它变成一个答案,因为这可能是你绊倒的原因。
-
关于多处理:
p.map将min_max应用于combinations的每个元素。看来您正在期待迭代器本身。 -
@Mad Physicist
index.append([i for i,x in enumerate(document) if x in searchTerms])生成一个索引值列表,该列表不区分哪个 searchTerm 生成的索引与在多个地方发现的相同 searchTerm 相对。这意味着距离不会在包含尽可能接近的所有 searchTerms 的文档中当场归零。我在这里错过了什么吗?
标签: python performance multiprocessing processing-efficiency coding-efficiency