快速搜索两个列表中的所有元素

时间:2014-12-08 20:26:41

标签: python performance algorithm search computer-science

假设我有两个大型列表,list_of_A_objects包含类A的对象,列表_of_B_objects包含B类对象。

他们都有字符串成员。

我希望能够搜索两个列表中的所有元素,如果A对象的字符串成员是B对象的字符串成员的子字符串,我希望它能够执行某些操作。

如果列表非常小,我在下面的内容很好,但如果列表很大,则可能需要很长时间。

有没有办法让它更快。我一直在考虑以某种方式使用字典,因为它们有快速查找但我无法弄明白。

这是我到目前为止所做的。

class A:
    def __init__(self, x):
        self.string = x

class B:
    def __init__(self,x):
        self.string = x

list_of_A_objects = get_large_list_of_A_objects()

list_of_B_objects = get_large_list_of_B_objects() 


for A_object in list_of_A_objects:
    for B_Object in list_of_B_objects:
        if A_object.string in B_Object.string:
            do_something()

2 个答案:

答案 0 :(得分:2)

您可以做的一件事是从B对象创建一个字符串。构建它时,还要创建索引列表,以便知道较大字符串中每个字符串的索引。请参阅下面的代码。

请注意,我不是python程序员,所以你必须解释我的伪代码。

BStrings = ""
list_of_Indexes = new list of int
for B_object in list_of_B_objects
    list_of_Indexes.Add(length of BStrings)
    BStrings = BStrings + B_Object.string + newline

现在,您可以搜索每个A_object的BStrings字符串。如果找到该字符串,该函数将返回在字符串中找到它的位置的索引。然后,您可以二进制搜索list_of_indexes以确定哪个B_object包含该字符串。

这并没有真正改变操作的复杂性(它仍然是MxN,其中M是A列表中的对象数,N是B列表的长度),但是搜索单个字符串中的子字符串将比循环遍历B列表更快,因为它避免了设置搜索的开销。

即使这样太慢,你也会想要使用像Aho-Corasick string matching algorithm这样的东西。可能有一个不错的Python实现。

答案 1 :(得分:0)

这是一个使用字典的python实现。首先将其中一个列表转换为由其对象的字符串

编制索引
a_map = {}

for A_object in list_of_A_objects:
    a_map[A_object.string] = A_object

然后对于另一个列表中的每个对象,检查对象的字符串是否存在于字典中(在常量时间内),如果是,那么do_something

for B_object in list_of_B_objects:
    if B_object.string in a_map:
        do_something(a_map[B_object.string])

这假设每个A_object都有一个唯一的字符串。如果不是这种情况,那么您可以将a_map的值设为对象数组而不是单个对象。