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

从元组列表中提取唯一值及其关联配对的实现方法

问题描述

我有如下格式的元组列表:

[
    ('a', 'AA'), # pair 1

    ('d', 'AA'), # pair 2
    ('d', 'a'),  # pair 3
    ('d', 'EE'), # pair 4

    ('b', 'BB'), # pair 5
    ('b', 'CC'), # pair 6
    ('b', 'DD'), # pair 7

    ('c', 'BB'), # pair 8
    ('c', 'CC'), # pair 9
    ('c', 'DD'), # pair 10

    ('c', 'b'),  # pair 11

    ('d', 'FF'), # pair 12

]

列表中的每个元组代表一组相似(或重复)的项对。我需要生成一个字典,其中键为元组中的某个唯一项,值为该键所有关联项组成的列表。例如:

  • 'a'与'AA'相似(配对1),'AA'又与'd'相似(配对2),'d'还与'EE'、'FF'相似(配对4、12),因此'a'对应的关联列表是['AA', 'd', 'EE', 'FF']
  • 'b'与'BB'、'CC'、'DD'相似(配对5-7),'c'又与这些项及'b'相似(配对8-11),因此'b'对应的关联列表是['BB', 'CC', 'DD', 'c']

预期输出示例:

{'a':['AA', 'd', 'EE', 'FF'], 'b':['BB', 'CC', 'DD', 'c']}

根据元组关系,['a', 'AA', 'd', 'EE', 'FF']属于同一相似组,组内任意项均可作为键,其余项为对应值,输出也可为:

{'AA':['a', 'd', 'EE', 'FF'], 'c':['BB', 'CC', 'DD', 'b']}

请问如何处理包含数千个此类元组的列表?


解决方案

处理这类连通分量分组问题,最适合的算法是并查集(Union-Find),它的时间复杂度接近O(n),处理数千个元组完全没问题。具体步骤如下:

1. 实现并查集数据结构

并查集主要包含两个核心操作:

  • find:查找某个元素的根节点(代表整个连通组)
  • union:将两个元素所在的连通组合并
class UnionFind:
    def __init__(self):
        self.parent = {}
    
    def find(self, x):
        # 路径压缩,加快后续查找速度
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]
    
    def union(self, x, y):
        # 先确保两个元素都在父字典中
        if x not in self.parent:
            self.parent[x] = x
        if y not in self.parent:
            self.parent[y] = y
        # 找到各自的根节点
        root_x = self.find(x)
        root_y = self.find(y)
        # 如果根不同,合并
        if root_x != root_y:
            self.parent[root_y] = root_x

2. 遍历元组列表,构建连通关系

把所有元组中的元素都加入并查集,完成分组:

pairs = [
    ('a', 'AA'),
    ('d', 'AA'),
    ('d', 'a'),
    ('d', 'EE'),
    ('b', 'BB'),
    ('b', 'CC'),
    ('b', 'DD'),
    ('c', 'BB'),
    ('c', 'CC'),
    ('c', 'DD'),
    ('c', 'b'),
    ('d', 'FF'),
]

uf = UnionFind()
for x, y in pairs:
    uf.union(x, y)

3. 生成目标字典

先把每个连通组的元素整理到一起,再为每个组选一个代表作为键,其余元素作为值:

# 第一步:按根节点分组
groups = {}
for item in uf.parent:
    root = uf.find(item)
    if root not in groups:
        groups[root] = []
    groups[root].append(item)

# 第二步:生成目标字典
result = {}
for root, members in groups.items():
    # 去掉根节点本身,剩下的就是关联项
    result[root] = [m for m in members if m != root]

print(result)

运行后输出示例(取决于根节点的选择,结果符合要求即可):

{'a': ['AA', 'd', 'EE', 'FF'], 'b': ['BB', 'CC', 'DD', 'c']}

如果想让每个组的任意元素都能作为键,可以扩展为:

full_result = {}
for members in groups.values():
    for key in members:
        full_result[key] = [m for m in members if m != key]

print(full_result['AA'])  # 输出: ['a', 'd', 'EE', 'FF']

内容的提问来源于stack exchange,提问作者Naveen Reddy Marthala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:20:29