Python:检查字符串及其子字符串是否存在于同一列表中

Python:检查字符串及其子字符串是否存在于同一列表中,python,nlp,Python,Nlp,我在一个标记化的句子中提取了基于1-gram、2-gram、3-gram的关键词 list_of_keywords = [] for i in range(0, len(stemmed_words)): temp = [] for j in range(0, len(stemmed_words[i])): temp.append([' '.join(x) for x in list(everygrams(stemmed_words[i][j], 1, 3)) if

我在一个标记化的句子中提取了基于1-gram、2-gram、3-gram的关键词

list_of_keywords = []
for i in range(0, len(stemmed_words)):
    temp = []
    for j in range(0, len(stemmed_words[i])):
        temp.append([' '.join(x) for x in list(everygrams(stemmed_words[i][j], 1, 3)) if ' '.join(x) in set(New_vocabulary_list)])
    list_of_keywords.append(temp)
我已经获得了关键字列表

['blood', 'pressure', 'high blood', 'blood pressure', 'high blood pressure']
['sleep', 'anxiety', 'lack of sleep']
如何简单地删除列表中的所有子字符串并保留结果:

['high blood pressure']
['anxiety', 'lack of sleep']

您可以使用这一行:

b = ['blood', 'pressure', 'high blood', 'blood pressure', 'high blood pressure']
result = [ i for i in b if not any( [ i in a for a in b if a != i]   )]
我承认这是O(n2),对于大输入,性能可能会很慢

这基本上是对以下内容的列表理解:

word_list =  ['blood', 'pressure', 'high blood', 'blood pressure', 'high blood pressure']

result = []
for this_word in word_list:
    words_without_this_word = [ other_word  for other_word in word_list if other_word != this_word]  
    found = False
    for other_word in words_without_this_word:
        if this_word in other_word:
            found = True

    if not found:
        result.append(this_word)

result

假设元素的顺序是从最短字符串到最长字符串,则需要检查每个元素是否为最后一个元素的子字符串,然后将其从列表中删除:

symptoms = ['blood', 'pressure', 'high blood', 'blood pressure', 'high blood pressure']


def removeSubstring(data):
    for symptom in data[:-1]:
        if symptom in data[-1]:
            print("Removing: ", symptom)
            data.remove(symptom)
    print(data)


removeSubstring(symptoms)

如果你有一大堆单词,最好使用

这是一份关于PyPI的报告

创建树后,可以调用
find_all(word)
来获取每次出现
word
的索引。您只需保留只出现一次的字符串:

from suffix_trees import STree
# https://pypi.org/project/suffix-trees/
# pip install suffix-trees

words = ['blood', 'pressure', 'high blood', 'blood pressure', 'high blood pressure'] + ['sleep', 'anxiety', 'lack of sleep']
st = STree.STree(words)

st.find_all('blood')
# [0, 20, 26, 46]

st.find_all('high blood pressure')
# [41]

[word for word in words if len(st.find_all(word)) == 1]
# ['high blood pressure', 'anxiety', 'lack of sleep']
words
需要是一个唯一的字符串列表,因此您可能需要在生成后缀树之前调用
list(set(words))


据我所知,整个脚本应该在
O(n)
中运行,
n
是字符串的总长度。

谢谢,但是你建议的方法只适用于1个最长的字符串,只需使用
症状=['血压','睡眠','高血压','睡眠不足']
在迭代列表时从列表中删除内容通常是一个非常糟糕的主意。@ChristianSloper您能详细说明原因吗?我相信删除内部列表理解会稍微快一点,这样它就会成为生成器理解,如下所示:
result=[I代表I在b中如果没有(I代表a代表a在b中如果a!=I)]
它似乎不起作用。例如,使用
grams=['abc','bc','a','b','c']
时,所有子字符串都会被一个空格分割吗?
['sub',string','substring']
应该变成什么?
grams = ['blood', 'pressure', 'high blood', 'blood pressure', 'high blood pressure']

unique_grams = [grams[i] for i in range(len(grams)) if not grams[i] in ' '.join(grams[i+1:])]
from suffix_trees import STree
# https://pypi.org/project/suffix-trees/
# pip install suffix-trees

words = ['blood', 'pressure', 'high blood', 'blood pressure', 'high blood pressure'] + ['sleep', 'anxiety', 'lack of sleep']
st = STree.STree(words)

st.find_all('blood')
# [0, 20, 26, 46]

st.find_all('high blood pressure')
# [41]

[word for word in words if len(st.find_all(word)) == 1]
# ['high blood pressure', 'anxiety', 'lack of sleep']