我目前正在处理一个超过200万行的文件。我已经将这些行分成了元素列表(例如:[a,b,c,d]
= 1行,单词分隔)。
我正在尝试使用以下代码遍历所有行:
for a in aud:
for esps in final:
if a[0] in final[esps]:
a[0] = esps
在第一个for循环中,我指的是200万+行。在第二个for循环中,它通过一个包含2010键的字典,每个键可能至少有50个相应的值。我想在行中找到等于字典中值的a[0]
元素。如果匹配,我将所选行中的a[0]
元素更改为字典键的值。
问题是这段代码需要花费很长时间才能运行,而且我对于优化以及如何更快地运行这一点并不了解太多(没有)。 如果有人能告诉我如何更快地做这样的事情,我会非常感谢。
答案 0 :(得分:25)
当你有“大”事情要做时,像这样,快速推进的关键是“降低算法的复杂性” - 也就是说,如果可能的话,避免任何依赖于任一数据集大小的操作。
在您给出的示例中,您为数百万行中的每一行执行50 x 2000线性搜索 - 这很多!问题在于,如果每个final[esps]
都是一个列表,Python会使用运算符in
在这50个值中执行线性搜索。
既然你提到你正在从文件中读取你的值,我必须假设[0]和final
行中的元素都是字符串 - 但这也适用于数字。
首先,非常简单的优化,只需将final
字典行从列表更改为set
s,set
运算符更改in
从线性到恒定时间(从O(m)到O(1)) - 所以,如果在运行示例中的代码之前,你基本上将搜索时间缩短了50倍:
for key in final:
final[key] = set(final[key])
但您仍然在final
的每个2010键中执行线性搜索。将其更改为常量搜索的方法是创建反向字典 - 其中final
行中的50个值中的每一个都指向键esp
。然后你只需使用[0]作为这个反向字典中的键 - 你将在100000项(2000 x 50)中替换线性搜索,以便在字典中以恒定时间进行搜索;
这很容易实现 - 只需将代码更改为:
rfinal = {}
for esp, values in final.items():
for value in values:
rfinal[value] = esp
for a in aud:
if a[0] in rfinal:
a[0] = rfinal[a[0]]
else:
# code for when there is no match for a[0]
...