Python中如何按条件连续合并列表元素?
连续合并符合数值阈值条件的列表元素问题
需求
处理包含字符与数值的列表,当元素间数值差≤指定阈值(此处为2)时,连续合并字符并保留该组最大数值,需在遍历过程中更新列表。
原代码问题
原代码仅能合并相邻两个符合条件的元素,无法完成连续合并。例如输入中的a、b、c应合并为a-b-c 3,但原输出仅得到a-b 2和c 3两组。
原代码及输入输出
""" 输入数据 a 1 b 2 c 3 g 7 j 10 k 11 o 15 p 16 q 17 r 18 v 22 目标是:当元素间的数值差≤指定阈值时,连续合并字符,并保留该组的最大数值;此处阈值设为2。 阈值为2时的预期输出: a-b-c 3 g 7 j-k 11 o-p-q-r 18 v 22 """ from pprint import pprint in_data = [['a', 1], ['b', 2], ['c', 3], ['g', 7], ['j', 10], ['k', 11], ['o', 15], ['p', 16], ['q', 17], ['r', 18], ['v', 22]] """阈值为2时的预期输出: [['a-b-c', 3], ['g', 7], ['j-k', 11], ['o-p-q-r', 18], ['v', 22]] """ print("input data:") pprint(in_data) for i, (x1, y1) in enumerate(in_data): for j, (x2, y2) in enumerate(in_data): if j <= i: continue if y2 - y1 <= 2: new_x = x1 + '-' + x2 new_y = max(y1, y2) in_data[i] = [new_x, new_y] del in_data[j] break print("updated input:") pprint(in_data)
当前运行输出
$ python merge_test.py input data: [['a', 1], ['b', 2], ['c', 3], ['g', 7], ['j', 10], ['k', 11], ['o', 15], ['p', 16], ['q', 17], ['r', 18], ['v', 22]] updated input: [['a-b', 2], ['c', 3], ['g', 7], ['j-k', 11], ['o-p', 16], ['q-r', 18], ['v', 22]]
问题分析
原代码使用两层for循环,每次仅合并当前索引i和第一个符合条件的j,删除j后直接break进入下一个i。这种逻辑无法处理合并后的元素与后续元素的连续匹配——例如合并a和b后,新元素a-b的数值为2,与c的数值3差值为1(≤2),但循环已移动到下一个索引,不会回头检查已合并的元素,导致连续合并失败。
解决方案
方法1:构建新列表(推荐)
逻辑清晰,避免修改原列表导致的索引混乱,直接遍历原列表构建结果组:
from pprint import pprint in_data = [['a', 1], ['b', 2], ['c', 3], ['g', 7], ['j', 10], ['k', 11], ['o', 15], ['p', 16], ['q', 17], ['r', 18], ['v', 22]] threshold = 2 result = [] if not in_data: pprint(result) exit() # 初始化当前合并组 current_chars, current_max = in_data[0] for char, num in in_data[1:]: if num - current_max <= threshold: # 符合条件,合并字符并更新最大值 current_chars += '-' + char if num > current_max: current_max = num else: # 不符合条件,将当前组存入结果,重置当前组 result.append([current_chars, current_max]) current_chars, current_max = char, num # 存入最后一个合并组 result.append([current_chars, current_max]) print("预期输出:") pprint(result)
输出结果
[['a-b-c', 3], ['g', 7], ['j-k', 11], ['o-p-q-r', 18], ['v', 22]]
方法2:直接修改原列表(while循环控制索引)
如果必须在遍历过程中更新原列表,使用while循环控制索引,确保合并后能重新检查当前位置的元素:
from pprint import pprint in_data = [['a', 1], ['b', 2], ['c', 3], ['g', 7], ['j', 10], ['k', 11], ['o', 15], ['p', 16], ['q', 17], ['r', 18], ['v', 22]] threshold = 2 i = 0 while i < len(in_data) - 1: current_x, current_y = in_data[i] next_x, next_y = in_data[i+1] if next_y - current_y <= threshold: # 合并当前元素与下一个元素 new_x = current_x + '-' + next_x new_y = max(current_y, next_y) in_data[i] = [new_x, new_y] # 删除下一个元素,索引不递增,继续检查当前位置的新元素 del in_data[i+1] else: # 不符合条件,移动到下一个元素 i += 1 print("更新后的列表:") pprint(in_data)
输出结果
与方法1一致,实现连续合并。
内容的提问来源于stack exchange,提问作者everestial
相关产品推荐
相关产品推荐

