Python如何删除嵌套列表中的反向相似及子集短语
问题分析
原代码无法得到预期结果的核心问题有两个:
- 没有处理语序颠倒的短语:直接用
in判断字符串包含,只能匹配字符顺序完全一致的子串,无法识别单词相同但语序不同的情况 - 判断逻辑有漏洞:弹出元素时仅判断当前元素是否存在于剩余未弹出的元素中,反过来如果剩余元素是更短的子集,不会过滤掉已弹出的短元素
解决思路
- 把每个短语拆分为无序的单词集合,忽略语序判断两个短语的包含关系
- 对每个子列表,遍历所有短语,仅保留不存在其他短语能完全包含它的所有单词的条目
- 额外支持按短语长度优先判断,可提升大列表处理效率,越长的短语越不可能是其他短语的子集
修改后代码
lst1 = [['daniel philips', 'philips daniel', 'daniel philips william'],['cherry', 'mary', 'cherry mary']] keyword_list = [] for list_a in lst1: # 把每个短语转成(单词集合, 原字符串)的元组,方便后续对比 phrase_tuples = [(set(item.split()), item) for item in list_a] temp_list = [] for words, phrase in phrase_tuples: is_subset = False for other_words, other_phrase in phrase_tuples: # 跳过和自身的对比 if phrase == other_phrase: continue # 判断当前短语的所有单词是不是都存在于另一个短语中 if words.issubset(other_words): is_subset = True break if not is_subset: temp_list.append(phrase) keyword_list.append(temp_list) print(keyword_list) # 输出结果:[['daniel philips william'], ['cherry mary']]
代码说明
- 用
set(item.split())把短语转成单词集合,天然忽略语序,只要单词完全一致,不管排列顺序都会被判定为相等 issubset()方法直接判断一个集合的所有元素是否都存在于另一个集合中,完美匹配“短短语是长短语子集”的判断需求- 遍历所有短语两两对比,只有没有其他短语能包含它的才会被保留,符合需求
内容的提问来源于stack exchange,提问作者Anonymous_Forte
相关产品推荐
相关产品推荐

