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

Python识别列表重叠合并,保证同公司下product_id跨列表唯一

解决思路

本质是对同公司下存在产品交集的集合做合并,用并查集(Union-Find)算法实现逻辑最清晰,步骤如下:

  • 每个公司单独处理,先把所有(set_id, 产品列表)转成(set_id, 产品集合),方便快速判断交集
  • 初始化并查集,所有set_id初始父节点为自身
  • 两两遍历同公司下的所有set,若两个set的产品集合交集不为空,则合并两个set的父节点
  • 按根节点分组,把同组所有set的产品合并去重,空产品列表的set无交集会单独保留
完整可运行代码
from collections import defaultdict

def find(u, parent):
    if parent[u] != u:
        parent[u] = find(parent[u], parent)
    return parent[u]

def union(u, v, parent):
    u_root = find(u, parent)
    v_root = find(v, parent)
    if u_root != v_root:
        parent[v_root] = u_root

def process_data(data):
    result = {}
    for company_id, set_list in data.items():
        # 存储每个set_id对应的产品集合
        set_product_map = {sid: set(plist) for sid, plist in set_list}
        # 初始化并查集父节点
        parent = {sid: sid for sid, _ in set_list}
        set_ids = list(set_product_map.keys())
        # 两两比较合并
        for i in range(len(set_ids)):
            s1 = set_ids[i]
            p1 = set_product_map[s1]
            # 空集合无交集,跳过
            if not p1:
                continue
            for j in range(i+1, len(set_ids)):
                s2 = set_ids[j]
                p2 = set_product_map[s2]
                if not p2:
                    continue
                # 有交集则合并
                if p1 & p2:
                    union(s1, s2, parent)
        # 按根节点分组合并产品
        group = defaultdict(set)
        for sid in set_ids:
            root = find(sid, parent)
            group[root].update(set_product_map[sid])
        # 转成要求的格式,产品排序可选
        result[company_id] = [(root, sorted(list(plist))) for root, plist in group.items()]
    return result

# 测试用示例数据
data = {
    83: [
        (128, []), 
        (129, [19283, 23837]), 
        (130, [29553]), 
        (133, [19283, 20070, 20072, 20087, 20095]), 
        (134, [20069, 20070, 20071, 20095, 20098])
    ],
    84: [
        (145, [2322,2211]), 
        (146, [2333, 2211]), 
        (152, [2333])
    ]
}

if __name__ == "__main__":
    res = process_data(data)
    print(res)
输出结果

运行上述代码输出完全符合要求:

{
    83: [
        (128, []), 
        (129, [19283, 20069, 20070, 20071, 20072, 20087, 20095, 20098, 23837]), 
        (130, [29553])
    ], 
    84: [(145, [2211, 2322, 2333])]
}

注:合并后用哪个set_id作为最终id由并查集合并顺序决定,符合「product_id合并到任意set_id下都可」的规则,如果需要指定优先保留更大/更小的set_id,修改union方法的父节点赋值逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 03:57:01