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

Python 快速搜索两个列表中的所有元素,python,performance,algorithm,search,computer-science,Python,Performance,Algorithm,Search,Computer Science,假设我有两个大列表,一个是包含类A对象的对象列表,另一个是包含类B对象的对象列表 它们都有字符串成员 我希望能够搜索两个列表中的所有元素,如果A对象的字符串成员是B对象的字符串成员的子字符串,我希望它做些什么 如果列表很小,我在下面得到的是很好的,但是如果列表很大,可能需要很长时间 有没有办法让这更快。我一直在考虑以某种方式使用字典,因为字典的查找速度很快,但我想不出来 这就是我目前所拥有的 class A: def __init__(self, x): self.str

假设我有两个大列表,一个是包含类A对象的对象列表,另一个是包含类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()

您可以做的一件事是从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_对象搜索BStrings字符串。如果找到字符串,函数将返回在字符串中找到该字符串的位置的索引。然后可以对索引列表进行二进制搜索,以确定哪个B_对象包含该字符串

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


如果这太慢了,那么您将需要使用类似的。可能有一个不错的Python实现可用。

这里是一个使用字典的Python实现。首先将其中一个列表转换为按其对象字符串编制索引的列表

a_map = {}

for A_object in list_of_A_objects:
    a_map[A_object.string] = A_object
然后,对于另一个列表中的每个对象,检查字典中是否存在该对象的字符串(在固定时间内),如果存在,则执行\u操作

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

这假设每个A_对象都有一个唯一的字符串。如果不是这样,那么您可以将一个映射的值设置为一个对象数组,而不是单个对象。

我并不关心执行某项操作所需的时间。上面的代码是我问题的一个简化示例。我真正的问题是,当一个列表变大时,另一个列表也变大了,所以当其中一个列表变大时,我会得到n^2的时间顺序。我问,因为找到第一个匹配与做某事或寻找多个匹配之间有很大的区别,我不认为一个集合或者一个dict可以帮助你,因为你正在寻找一个子串好的,我明白你的意思。它需要搜索多个匹配项。谢谢字符串有什么限制吗?如果它们是一般的字符串,那么似乎很难比二次复杂度做得更好,但是如果它们是特殊的,可能会有一些技巧。谢谢你花时间回答,我会考虑一下。