Python遍历嵌套列表并按条件处理元素的实现问题
嵌套列表数据的批量处理需求及解决方案
数据结构说明
处理大数据集后生成嵌套列表act_all_fun,结构如下:
- 最外层:按星期几分组(示例仅展示前2天数据)
- 第二层:每天的时间条目列表
- 单个条目格式:
[datetime.time对象, 数值, 标识字符串, 分组标识]
处理需求
遍历每个时间条目,按以下规则修改条目数值(第二个元素):
- 当条目数值为254时:
- 统计当天内所有数值为254的条目中,第三个元素(标识字符串)的唯一值数量
- 对每个唯一标识字符串的首次出现条目,将数值从254减1(即变为253)
- 当条目数值不等于254时:
- 统计当天内所有数值相同的条目中,第三个元素(标识字符串)的唯一值数量
- 对每个唯一标识字符串的首次出现条目,将数值加30(比如数值15的首次出现条目变为45)
示例数据
import datetime act_all_fun = [[[datetime.time(0, 0), 254, 'F37', 'd1'], [datetime.time(2, 0), 254, 'F7', 'd1'], [datetime.time(5, 0), 254, 'F17', 'd1'], [datetime.time(6, 30), 254, 'F37', 'd1'], [datetime.time(7, 0), 15, 'F37', 'd1'], [datetime.time(10, 0), 17, 'F37', 'd0'], [datetime.time(12, 0), 19, 'F37', 'd0'], [datetime.time(21, 0), 15, 'F7', 'd1'], [datetime.time(23, 0), 254, 'F37', 'd1']], [[datetime.time(0, 0), 254, 'F37', 'd1'], [datetime.time(1, 30), 254, 'F', 'd1'], [datetime.time(5, 0), 2, 'F7', 'd1'], [datetime.time(6, 30), 2, 'F37', 'd0'], [datetime.time(8, 0), 7, 'F37', 'd0'], [datetime.time(9, 15), 11, 'F', 'd0'], [datetime.time(10, 15), 15, 'F', 'd0'], [datetime.time(15, 30), 5, 'F37', 'd0'], [datetime.time(16, 15), 6, 'F', 'd0'], [datetime.time(19, 30), 9, 'F37', 'd0'], [datetime.time(23, 0), 254, 'F37', 'd1']]]
尝试的代码(未得到预期结果)
for day in act_all_fun: for act in day: if act[1] in range(240,255) and act[2] not in [x[2] for x in day if x != act]: act[1] = act[1] - 1
试过扁平化列表、转为DataFrame等方法,均未解决问题,求正确实现方案。
正确实现方案
按天分组,分别记录每个规则下的已处理标识,遍历条目时判断是否为首次出现,再执行修改操作:
import datetime def process_act_data(act_data): processed_data = [] for day in act_data: # 记录当天内数值为254的已处理标识 seen_254 = set() # 记录当天内非254数值对应的已处理标识(key为数值,value为标识集合) seen_other = {} processed_day = [] for entry in day: time_val, num, tag, group = entry # 复制原条目避免修改原始数据,需直接修改原数据可操作entry new_entry = [time_val, num, tag, group] if num == 254: if tag not in seen_254: new_entry[1] = num - 1 seen_254.add(tag) else: if num not in seen_other: seen_other[num] = set() if tag not in seen_other[num]: new_entry[1] = num + 30 seen_other[num].add(tag) processed_day.append(new_entry) processed_data.append(processed_day) return processed_data # 处理数据 result = process_act_data(act_all_fun) # 打印处理后的第一天数据示例 print("处理后的第一天数据:") for item in result[0]: print(item)
代码说明
- 按天维护两个记录集合:
seen_254:追踪当天数值为254的条目中已处理过的标识字符串seen_other:字典结构,按数值分类追踪非254条目中已处理的标识字符串
- 遍历条目时:
- 数值为254:若标识未被记录,则修改数值并加入集合
- 数值非254:先初始化对应数值的标识集合,再判断标识是否已处理,未处理则修改数值并加入集合
- 代码默认生成新列表保存结果,若需修改原始数据,可直接操作
entry而非创建new_entry
内容的提问来源于stack exchange,提问作者HOSSAM
相关产品推荐
相关产品推荐

