You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于name键过滤列表重复对象,按规则保留目标元素?

问题描述

给定如下对象列表:

[
 Phone('name': 'iPhone-14', 'updated_date': '2022-11-12', 'status': 'available'),
 Phone('name': 'iPhone-14', 'updated_date': '2023-10-12', 'status': 'sold'),
 Phone('name': 'Samsung-S20', 'updated_date': '2022-10-12', 'status': 'available'),
 Phone('name': 'Samsung-S20', 'updated_date': '2020-10-12', 'status': 'available'),
 Phone('name': 'Samsung-S10', 'updated_date': '2020-10-12', 'status': 'sold'),
 Phone('name': 'iPhone-14', 'updated_date': '2022-04-01', 'status': 'available'),
 Phone('name': 'Samsung-S10', 'updated_date': '2022-12-11', 'status': 'sold'),
]

需求:针对每个name分组,保留该组中updated_date最新且status为available的对象;若该组无available状态的对象,则保留updated_date最新的对象。

预期处理结果:

[
 Phone('name': 'iPhone-14', 'updated_date': '2022-11-12', 'status': 'available'),
 Phone('name': 'Samsung-S20', 'updated_date': '2022-10-12', 'status': 'available'),
 Phone('name': 'Samsung-S10', 'updated_date': '2022-12-11', 'status': 'sold'),
]

请问无需多层嵌套循环的最高效实现方式是什么?


高效实现方案

这里提供两种无多层嵌套循环的高效实现方式,适用于不同场景:

方法1:字典跟踪最优项(时间复杂度O(n))

直接遍历所有对象,用字典记录每个name对应的最优对象,遍历过程中实时对比更新,全程只需一次遍历:

from datetime import datetime

def get_best_phones(phones):
    best_map = {}
    for phone in phones:
        name = phone.name  # 若Phone是字典则用phone['name']
        current_date = datetime.strptime(phone.updated_date, '%Y-%m-%d')
        current_status = phone.status

        if name not in best_map:
            best_map[name] = phone
            continue
        
        existing = best_map[name]
        existing_date = datetime.strptime(existing.updated_date, '%Y-%m-%d')
        existing_status = existing.status

        # 优先保留available状态,同状态则选日期最新的
        if current_status == 'available':
            if existing_status != 'available' or current_date > existing_date:
                best_map[name] = phone
        else:
            if existing_status != 'available' and current_date > existing_date:
                best_map[name] = phone
    
    return list(best_map.values())

该方法是线性时间复杂度,数据量越大优势越明显,适合处理大规模数据集。

方法2:排序后分组(时间复杂度O(n log n))

先按规则排序,再用itertools.groupby分组取每组首项,代码更简洁易读:

from itertools import groupby
from datetime import datetime

def get_best_phones(phones):
    # 排序规则:按name分组 -> available状态优先 -> 日期倒序(最新在前)
    def sort_key(phone):
        date = datetime.strptime(phone.updated_date, '%Y-%m-%d')
        status_priority = 0 if phone.status == 'available' else 1
        return (phone.name, status_priority, -date.timestamp())
    
    sorted_phones = sorted(phones, key=sort_key)
    # 按name分组后取每组第一个元素
    return [next(group) for _, group in groupby(sorted_phones, key=lambda x: x.name)]

该方法代码更紧凑,可读性强,数据量较小时性能足够优秀。

内容的提问来源于stack exchange,提问作者Mikael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 10:42:47