将列表元素分组排序为子列表:后续元素为前序元素子串
问题描述
给定字符串列表:
x = ['long stories about hard yarn', 'The bears', 'unpleasant', 'The bears endure tiring', 'The bears endure', 'tiring and unpleasant', 'long stories', 'hard yarn', 'tiring', 'The bears endure tiring and unpleasant']
期望生成以最长主串开头,后续依次包含层级化子串的分组列表:
[['The bears endure tiring and unpleasant', 'tiring and unpleasant', 'tiring'], ['The bears endure tiring and unpleasant', 'tiring and unpleasant', 'unpleasant'], ['The bears endure tiring and unpleasant', 'The bears endure tiring', 'tiring'], ['The bears endure tiring and unpleasant', 'The bears endure tiring', 'The bears endure', 'The bears'], ['long stories about hard yarn', 'long stories'], ['long stories about hard yarn', 'hard yarn']]
当前使用以下代码生成了有效匹配,但输出是两两配对的散列表,未按主串分组并排序:
from itertools import combinations, permutations perm = permutations(x, 2) simlr = [] for i,j in list(perm): if len(i) > len(j): if check(i,j): # 假设check是判断j是i子串的函数 simlr.append([i,j]) simlr
当前输出:
[['long stories about hard yarn', 'long stories'], ['long stories about hard yarn', 'hard yarn'], ['The bears endure tiring', 'The bears'], ['The bears endure tiring', 'The bears endure'], ['The bears endure tiring', 'tiring'], ['The bears endure', 'The bears'], ['tiring and unpleasant', 'unpleasant'], ['tiring and unpleasant', 'tiring'], ['The bears endure tiring and unpleasant', 'The bears'], ['The bears endure tiring and unpleasant', 'unpleasant'], ['The bears endure tiring and unpleasant', 'The bears endure tiring'], ['The bears endure tiring and unpleasant', 'The bears endure'], ['The bears endure tiring and unpleasant', 'tiring and unpleasant'], ['The bears endure tiring and unpleasant', 'tiring']]
解决方案
核心思路:
- 明确
check函数逻辑,确保子串是完整短语匹配 - 按字符串长度降序排序,优先处理最长主串
- 递归生成从主串到最底层子串的完整层级路径
- 去重并整理成目标格式
优化后的代码:
def check(parent, child): # 确保child是parent的完整短语,避免部分字符匹配误判 return child in parent and ( parent.startswith(child + ' ') or parent.endswith(' ' + child) or ' ' + child + ' ' in parent ) x = ['long stories about hard yarn', 'The bears', 'unpleasant', 'The bears endure tiring', 'The bears endure', 'tiring and unpleasant', 'long stories', 'hard yarn', 'tiring', 'The bears endure tiring and unpleasant'] # 按长度降序排序,优先处理最长字符串 sorted_x = sorted(x, key=lambda s: -len(s)) result = [] processed = set() for main_str in sorted_x: if main_str in processed: continue # 筛选当前主串的所有有效子串 children = [s for s in x if len(s) < len(main_str) and check(main_str, s)] if not children: continue # 递归构建完整层级路径 def build_paths(current, path): sub_children = [s for s in children if len(s) < len(current) and check(current, s)] if not sub_children: result.append(path.copy()) return for sub in sub_children: path.append(sub) build_paths(sub, path) path.pop() # 为每个一级子串启动路径构建 for child in children: build_paths(child, [main_str, child]) # 标记已处理字符串,避免重复生成 processed.add(main_str) processed.update(children) # 去重处理 unique_result = [] seen = set() for path in result: path_tuple = tuple(path) if path_tuple not in seen: seen.add(path_tuple) unique_result.append(path) print(unique_result)
代码说明
check函数:避免部分字符匹配(比如"tire"误匹配"tiring"),确保子串是独立短语- 排序逻辑:优先处理最长字符串,保证主串的唯一性
- 递归路径构建:生成从主串到最底层子串的完整层级链,符合期望结构
- 去重处理:避免同一路径被多次生成
内容的提问来源于stack exchange,提问作者sharathchandramandadi
相关产品推荐
相关产品推荐

