在python中搜索大型列表
我有两个列表:list在python中搜索大型列表,python,search,substring,data-processing,Python,Search,Substring,Data Processing,我有两个列表:list消息和list关键字。列表消息如下所示: message = ["my name is blabla",'x-men is a good movie','i deny that fact'] keyword = ['x-men','name is','psycho movie'] 我想创建一个新列表,其中包含消息中存在的关键字 newList = [] for message_index in message: print(newList) for key
消息
和list关键字
。列表消息
如下所示:
message = ["my name is blabla",'x-men is a good movie','i deny that fact']
keyword = ['x-men','name is','psycho movie']
我想创建一个新列表,其中包含消息中存在的关键字
newList = []
for message_index in message:
print(newList)
for keyword in keywords:
if search(r'\b{}\b'.format(keyword), message_index):
newList.append(keyword)
上面是我的python代码,问题是我的消息列表中的每个句子大约是100到150个单词,列表的长度是3000。每个关键字可能是一个或两个单词,列表的长度是12000
所以搜索需要很长时间,有没有更短的方法
由于两个列表中都有大量数据,因此此问题有所不同。具有内置功能:
要按简单引用进行搜索,请执行以下操作:
message = ["my name is blabla",'x-men is a good movie','i deny that fact']
keyword = ['x-men','name is','psycho movie']
result = [k for k in keyword if any(k in m for m in message)]
print(result)
输出:
['x-men', 'name is']
------------
如果您需要按精确的单词进行搜索:
import re
message = ["my name is blabla",'x-men is a good movie','i deny that fact']
keyword = ['x-men','name is','psycho movie']
result = [k for k in keyword if any(re.search(r'\b{}\b'.format(k), m) for m in message)]
具有内置功能:
要按简单引用进行搜索,请执行以下操作:
message = ["my name is blabla",'x-men is a good movie','i deny that fact']
keyword = ['x-men','name is','psycho movie']
result = [k for k in keyword if any(k in m for m in message)]
print(result)
输出:
['x-men', 'name is']
------------
如果您需要按精确的单词进行搜索:
import re
message = ["my name is blabla",'x-men is a good movie','i deny that fact']
keyword = ['x-men','name is','psycho movie']
result = [k for k in keyword if any(re.search(r'\b{}\b'.format(k), m) for m in message)]
尝试使用嵌套列表
list = [key for key in keyword for word in message if key in word]
尝试使用嵌套列表
list = [key for key in keyword for word in message if key in word]
通过将列表
消息
连接到分隔字符串中,然后搜索该字符串中的每个关键字,可以显著降低关键字搜索的复杂性:
>>> ms='\t'.join(message)
>>> [e for e in keyword if e in ms]
['x-men', 'name is']
同样的方法也适用于具有相同好处的正则表达式:
>>> [e for e in keyword if re.search(r'\b'+e+r'\b', ms)]
这将复杂性从
O(M*N)
降低到O(N)
。您可以通过将列表消息
加入一个分隔字符串,然后搜索该字符串中的每个关键字来显著降低关键字搜索的复杂性:
>>> ms='\t'.join(message)
>>> [e for e in keyword if e in ms]
['x-men', 'name is']
同样的方法也适用于具有相同好处的正则表达式:
>>> [e for e in keyword if re.search(r'\b'+e+r'\b', ms)]
这将复杂性从
O(M*N)
降低到O(N)
。是否希望每个出现的关键字只出现一次?您似乎在使用re.search
,而不是子字符串搜索。您真正需要哪一个?是否希望每个出现的关键字只出现一次?您似乎在使用re.search
,而不是子字符串搜索。你真的需要哪一个?和任何的可能重复都会在第一次True
时有效中断。我认为这仍然不能解决一般性能问题。复杂性仍然是O(M*N)
如果不是大多数关键字出现在大多数消息中,让人感觉到提前中断的话。@schwobasegll,我想,无论是set
object还是二进制搜索都不适用于有词边界的搜索。请随意介绍一种更有效的方法。不过,在NLP中查找子字符串列表的方法还有其他算法。例如,您可以将关键字列表转换为树结构,并在遍历文本时保持在树中的位置。但这似乎超出了本线程的范围:)例如,请参见@RomanPerekhrest!我无意冒犯你。与OP的代码相比,这无疑是一个显著的改进。而且任何
都将在第一次True
时有效中断。我认为这仍然不能解决一般性能问题。复杂性仍然是O(M*N)
如果不是大多数关键字出现在大多数消息中,让人感觉到提前中断的话。@schwobasegll,我想,无论是set
object还是二进制搜索都不适用于有词边界的搜索。请随意介绍一种更有效的方法。不过,在NLP中查找子字符串列表的方法还有其他算法。例如,您可以将关键字列表转换为树结构,并在遍历文本时保持在树中的位置。但这似乎超出了本线程的范围:)例如,请参见@RomanPerekhrest!我无意冒犯你。这无疑是对OP代码的重大改进。