Itertools.combinations大型列表的性能问题

时间:2015-03-05 16:10:54

标签: python

我在tickers_list中有一个代码清单,我需要组合这些独特的元素。

这是我的代码:

corr_list = []
i = 0
for ticker in tickers_list:
    tmp_list = tickers_list[i+1:]
    for tl_ticker in tmp_list:
        corr_list.append({'ticker1':ticker, 'ticker2':tl_ticker})
    i = i+1
len(corr_list)

以下是使用iteritems的代码:

from itertools import combinations
result = combinations(tickers_list, 2)
new_list = [{'ticker1':comb[0], 'ticker2':comb[1]} for comb in combinations(tickers_list, 2)]
len(new_list)

产生完全相同的结果。当然,iteritems代码更优雅,并且完美适用于10,100和1,000项。所需时间几乎相同(我计时)。但是,在4,000个项目中,我的代码在我的机器上运行大约需要12秒,同时iteritems会崩溃我的计算机。发送的结果只有大约20米行,所以我做错了什么或这是iteritems的问题?

1 个答案:

答案 0 :(得分:1)

from itertools import combinations, product

# 20 * 20 * 20 == 8000 items
tickers_list = ["".join(chars) for chars in product("ABCDEFGHIJKLMNOPQRST", repeat=3)]

# 8000 * 7999 / 2 == 31996000 (just under 32 million) items
unique_pairs = [{"ticker1":t1, "ticker2":t2} for t1,t2 in combinations(tickers_list, 2)]

在我的机器(Win7Pro x64,Python 3.4)上运行良好,最高可达len(tickers_list) == 8000(耗时38秒,消耗差不多76 GiB的RAM!)。

您运行的是32位还是64位Python?你真的需要存储所有组合,还是可以随意使用和丢弃它们?


编辑:我错误估算了尺寸;它实际上大约是9.5 GiB。亲自尝试一下:

from sys import getsizeof as size

size(unique_pairs) + len(unique_pairs) * size(unique_pairs[0])

给出了

9479596592  # total size of structure in bytes == 9.5 GiB 

无论如何,这不是使用itertools的结果;它是结果列表的内存占用量,无论你如何生成它都是相同的。无论如何,您的计算机都可以使用虚拟RAM(交换到磁盘)来处理它,尽管速度要慢得多。

如果您只是为了将其放入数据库,我建议让数据库完成工作:创建一个包含tickers_list项目的表,然后选择一个交叉连接来生成最终表,如

SELECT a.ticker, b.ticker
FROM
    tickers as a,
    tickers as b
WHERE
    a.ticker < b.ticker