从列表理解中返回两个列表 - 性能

时间:2014-04-22 09:57:06

标签: python list-comprehension

在我的程序中,我获取所有目录和文件(walk),然后将所有目录和文件作为键和路径作为值写入字典,然后从接口({{1})获取关键字})并将所有匹配返回到两个列表。我将展示它们(tk.Entry)并打开所选的一个(tk.Listbox)。

我使用this一个来创建两个列表,只有一个理解。在评论中,它说“只运行两个单独的列表推导更简单,但可能更快。”所以这让我对使用哪一个感到困惑。因为这个程序将运行我现在没有的~3TB数据,所以我无法运行,看哪哪个会更快。

这是我的最小化代码,我分别删除了win32shellkeywrd变量的接口和定义的关键字和路径。

folder

正如我上面提到的,我的问题是在处理大量数据时哪一个会更快?

2 个答案:

答案 0 :(得分:3)

使用zip()

results, paths = zip(*((k, v) for k, v in lines.items() if keywrd in k))

因为这将一步产生两个列表。另一种方法是使用一个for循环

results = []
paths = []
for (k,v) in lines.items():
    if keywrd in k:
        results.append(k)
        paths.append(v)

如果你想构建一个列表,列表理解是很好的;如果您需要来自同一循环的多个,只需使用循环。

但是,由于此数据来自SQLite查询,因​​此最好的办法是让 SQLite 将行限制为匹配的行:

data.execute("select * from audio if filename LIKE ?", ('%{}%'.format(keywrd),))

使用词典理解可以更有效地构建lines词典:

musics = data.execute("select * from audio")
lines = {row[1]: row[0] for row in musics}

或使用更具体的查询和光标上的直接循环:

data.execute("SELECT path, filename FROM audio WHERE filename LIKE ?",
             ('%{}%'.format(keywrd),))
paths, results = zip(*data)
对于两边都带有LIKE通配符的字符串,

%会产生相同的结果,并在Python中进行in测试;如果keywrd中包含filename,则匹配。

现在也不需要创建中间词典。

答案 1 :(得分:1)

更快的是使用for循环:

results = []; add_result = result.append
paths = []; add_path = path.append
for k,v in lines.items():
    if keywrd in k:
        add_result(k)
        add_path(v)

最快的是使用你的内存中的sqlite数据库来进行过滤。