优化python循环

时间:2014-09-05 20:29:51

标签: python performance optimization

以下循环在我的程序中创建了一个巨大的瓶颈。特别是因为记录可以超过500k。

records = [item for sublist in records for item in sublist] #flatten the list
for rec in records:
    if len(rec) > 5:
        tag = '%s.%s' %(rec[4], rec[5].strip())
        if tag in mydict:
            mydict[tag][0] += 1
            mydict[tag][1].add(rec[6].strip())
        else:
            mydict[tag] = [1, set(rec[6].strip())]

我没有看到一种方法,我可以用字典/列表理解来做到这一点,我不确定调用地图会对我有多大帮助。有没有办法优化这个循环?

编辑:字典包含有关程序中发生的某些操作的信息。 rec[4]是包含操作的包,rec[5]是操作的名称。原始日志包含int而不是实际名称,因此当将日志文件读入列表时,将查找int并将其替换为操作名称。增量计数器计算执行操作的次数,并且该组包含操作的参数。我正在使用一个集合,因为我不希望重复参数。条带只是为了去除空白区域。这个空格的存在在rec[6]中是不可预测的,但在rec[4]rec[5]中是一致的。

2 个答案:

答案 0 :(得分:6)

您可以使用itertools.chain.from_iterable直接遍历其展平的迭代器,而不是扁平化这么大的列表。

from itertools import chain

for rec in chain.from_iterable(records):
    #rest of the code

这比同等嵌套的基于for循环的genexp版本快3倍左右:

In [13]: records = [[None]*500]*10000

In [14]: %%timeit
    ...: for rec in chain.from_iterable(records): pass
    ...: 
10 loops, best of 3: 54.7 ms per loop

In [15]: %%timeit
    ...: for rec in (item for sublist in records for item in sublist): pass
    ...: 
10 loops, best of 3: 170 ms per loop

In [16]: %%timeit #Your version
    ...: for rec in [item for sublist in records for item in sublist]: pass
    ...: 
1 loops, best of 3: 249 ms per loop

答案 1 :(得分:3)

我不知道这是否会使它更快或更快,而不是......

if tag in mydict:
    mydict[tag][0] += 1
    mydict[tag][1].add(rec[6].strip())
else:
    mydict[tag] = [1, set(rec[6].strip())]
你可以试试......

element = mydict.setdefault(tag, [0, set()])
element[0] += 1
element[1].add(rec[6], strip())