删除列表元素时原列表无变化,如何保留item_id对应最大event_id的字典
问题原因
你遇到的核心问题是遍历列表的同时直接删除列表元素:
Python 对列表执行 for 循环遍历时,本质是通过迭代器按索引顺序读取元素。当你删除当前索引的元素后,列表中后续所有元素会自动向前移动一位,下一次迭代会直接读取+1后的索引位置,就会跳过原本应该被遍历的下一个元素,导致部分符合删除条件的元素没有被检测到,自然不会被删除,最终呈现出列表没有被修改的错觉。
举个简单示例:假设要遍历[1,2,3,4]删除所有小于3的元素,第一次读取索引0的元素1,符合删除条件,删除后列表变为[2,3,4],下一次迭代直接读取索引1的元素3,就跳过了索引0的元素2,最终2没有被删除,和你遇到的漏删逻辑一致。
除此之外你的代码还有效率问题:每次判断都要遍历整个子列表计算对应item_id的最大event_id,数据量大时运行速度会非常慢。
正确实现方案
建议先遍历一次子列表提前统计每个item_id对应的最大event_id,再通过生成新列表的方式过滤元素,完全避免遍历过程中修改原列表:
for el in lst: # 第一步:先统计当前订单下每个商品的最大event_id item_max_event = {} for item in el: iid = item['item_id'] if iid not in item_max_event or item['event_id'] > item_max_event[iid]: item_max_event[iid] = item['event_id'] # 第二步:过滤出符合条件的元素,直接替换原列表内容 el[:] = [item for item in el if item['event_id'] == item_max_event[item['item_id']]]
这里使用el[:] = ...而不是el = ...,是为了直接修改原列表的内存内容,而不是创建新的局部变量,保证外层的lst会同步更新。
运行后得到的结果完全符合需求:
[[{'event_id': 2, 'order_id': 1, 'item_id': 1, 'count': 1, 'return_count': 0, 'status': 'OK'}], [{'order_id': 2, 'event_id': 2, 'item_id': 1, 'count': 3, 'return_count': 1, 'status': 'OK'}, {'order_id': 2, 'event_id': 1, 'item_id': 2, 'count': 4, 'return_count': 2, 'status': 'OK'}]]
内容的提问来源于stack exchange,提问作者Mansur
相关产品推荐
相关产品推荐

