Python中如何按值变化对列表元素分组?含连续同值分组需求
按对话交互分组消息类型的Python实现
原始消息类型列表
msg_type = ["sent-message", "received-message", "received-message", "sent-message", "received-message", "sent-message", "received-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "received-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "received-message", "sent-message", "received-message"]
分组需求
需要将列表按对话交互逻辑分组:
- 连续相同类型的消息归为同一子组
- 连续的
sent-message视为一个整体,与后续连续的received-message(同样视为整体)组成一次完整对话交互 - 最终期望得到的分组索引结果:
conversations = [(0,2), (3,4),(5,7),(8,10), (11,13), (14,16),(17,19),(20,22),(23,24),(25,26)]
实现代码
msg_type = ["sent-message", "received-message", "received-message", "sent-message", "received-message", "sent-message", "received-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "received-message", "received-message", "sent-message", "sent-message", "received-message", "sent-message", "received-message", "sent-message", "received-message"] conversations = [] if msg_type: # 第一步:按连续相同类型预分组,记录每个子组的起止索引 pre_groups = [] start_idx = 0 current_type = msg_type[0] for idx in range(1, len(msg_type)): if msg_type[idx] != current_type: pre_groups.append((start_idx, idx - 1)) start_idx = idx current_type = msg_type[idx] pre_groups.append((start_idx, len(msg_type) - 1)) # 第二步:合并成对话交互组 idx = 0 while idx < len(pre_groups): # 遇到sent组,尝试合并后续的received组 if msg_type[pre_groups[idx][0]] == "sent-message": if idx + 1 < len(pre_groups) and msg_type[pre_groups[idx+1][0]] == "received-message": conv_start = pre_groups[idx][0] conv_end = pre_groups[idx+1][1] conversations.append((conv_start, conv_end)) idx += 2 else: # 处理末尾仅存sent组的边界情况 conversations.append(pre_groups[idx]) idx += 1 else: # 处理开头为received组的边界情况 conversations.append(pre_groups[idx]) idx += 1 print(conversations)
逻辑说明
- 预分组阶段:遍历列表,将连续相同类型的消息拆分独立子组,记录每个子组的起止索引,为后续合并做准备。
- 对话合并阶段:遍历预分组结果,将
sent-message子组与紧随其后的received-message子组合并为一个对话交互组,完全匹配需求中的分组规则。
内容的提问来源于stack exchange,提问作者Sanket Wagh
相关产品推荐
相关产品推荐

