有没有更快的方法从另一个列表中搜索项目?

时间:2015-05-04 20:39:51

标签: python list

我有两个带文件名的列表。第二个列表中的名称包含第一个名称中的名称,例如:

lst1 = ['file1', 'file2', 'file3']
lst2 = ['file2_processed', 'file1_processed', 'file3_processed']

lst2中的文件名与lst1中的文件名不同,这就是问题所在。

我需要获得一对包含lst1条目和相应lst2条目的列表,例如:

lst3 = [['file1', 'file1_processed'],
        ['file2', 'file2_processed'],
        ['file3', 'file3_processed']]

我想出的就是这个功能:

def pairs(a, b):
    c = []
    for wa in a:
        for wb in b:
            if wa in wb:
                c.append([wa, wb])
    return c

但是这个在巨大的列表上真的很慢,所以我在这里问:有没有更快的方法来执行此操作?

4 个答案:

答案 0 :(得分:1)

我不确定它会减慢多少,但是这样做的简单易懂的方法是:

def pair(a,b): 
    c = ''.join(b.split('_processed'))
    return a == c
lst3 = [[x,y] for x in lst1 for y in lst2 if pair(x,y)]

虽然可能比其他答案慢一点。

答案 1 :(得分:0)

如果您关注O(n^2)列表的创建,那么我建议您使用itertools模块中的迭代器:

import itertools as it

def parse(haystack, needle):
    return (x for x in it.product(haystack, needle) where x[1] in x[0])

另一种可能的优化:如果模式始终在<x>中找到<x>_processed,那么您可能需要调用in方法,而不是使用str.startwiths运算符:

return (x for x in it.product(haystack, needle) where x[0].startswith(x[1]))

当然.txt会妨碍......

订单有意义吗?如果不是,您可能想要对两个列表进行排序,并仅搜索大海捞针的相关部分。

答案 2 :(得分:0)

执行此操作的最佳方法可能是使用列表理解来完成所有操作,但完全按照您的要求完成。如果您要比较两个排序列表,那么确实没有比O(n ^ 2)更快的算法。请注意,如果您必须制作多个,则排序lst2并使用itertools.groupby按前缀分组几乎总是更快。

lst1 = ['file1.txt', 'file2.txt', 'file3.txt']
lst2 = ['file2_processed.txt', 'file1_processed.txt', 'file3_processed.txt']

lst3 = [(prefix, [fullname for fullname in lst2 if fullname.startswith(prefix)]) for
        prefix in lst1]

正如我上面提到的,如果您构建的不止一个,那么itertools.groupby可能会更好:

from itertools import groupby

lst1_set = set(lst1)  # faster lookups
lst2.sort()  # groupby must operate on a sorted list
lst3 = [(prefix, values) for prefix,values in groupby(
    lst2, lambda s: s.split('_')[0]) if prefix in lst1_set

事实上,这个例子阐明了一个可能更适合你的不同程序:

lst1_set = set(lst1)  # set lookups are O(1)
lst3 = []
for s in lst2:
    prefix = s.split("_")[0]
    if prefix in lst1_set:
        lst3.append((prefix, s))

答案 3 :(得分:0)

没有(请原谅我)尝试编写实际的Python代码来演示我的想法,在这种情况下应用的另一个好策略是使用关联数组。 (即&#34;字典。&#34;)

首先,遍历lst1在字典中为在那里找到的每个密钥创建一个虚拟条目。

现在,单独循环lst2。将字符串file2_processed拆分为file2processed。现在,看看第一部分(&#34; file2&#34;)是否在字典中。 (如果不是,为什么不呢?)将第二部分(&#34;已处理&#34;)存储到该词典条目插槽中。

Python字典专门用于生成与任何密钥相关联的(一个)...非常快......或者得出这样的条目不存在的结论。它通常是一种非常好的避免搜索的策略,几乎可以用任何编程语言编写。

然后,您可以遍历字典中的所有keys,或者遍历&#34;密钥及其相关值,&#34;产生最终结果。请注意,按键可以按任何特定顺序生成。