Python循环优化

时间:2017-05-07 02:36:03

标签: python dictionary

我目前正在处理一个超过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]元素更改为字典键的值。

问题是这段代码需要花费很长时间才能运行,而且我对于优化以及如何更快地运行这一点并不了解太多(没有)。 如果有人能告诉我如何更快地做这样的事情,我会非常感谢。

1 个答案:

答案 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]
       ...