繁体   English   中英

从元组列表中获取唯一值及其后续对

[英]Getting Unique Values and their Following Pairs from a List of Tuples

我有一个这样的元组列表:

[
    ('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 对),后者又类似于“d”(第 2 对),“d”类似于“EE”和“FF”(第 4 对和第 12 对) . 其他项目也是如此。

我预期的 output 是:

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

根据元组, ['a', 'AA', 'd', 'EE', 'FF']是相似的; 因此,其中任何一项都可以成为关键,而其余项目将成为它的价值。 所以,output 也可以是: {'AA':['a', 'd', 'EE', 'FF'], 'c':['BB', 'CC', 'DD', 'b']} 因此,output 字典的键可以是重复对中的任何内容。

对于列表中包含数千个此类元组的列表,我该如何执行此操作?

您可以使用 3 部词典,一部用于 output ( out ),一部用于跟踪可见值 ( seen ),一部用于 map 等键 ( mapper ):

out = {}
seen = {}
mapper = {}

for a, b in l:
    if b in seen:
        out.setdefault(seen[b], []).append(a)
        mapper[a] = seen[b]
    else:
        out.setdefault(mapper.setdefault(a, a), []).append(b)
        seen[b] = a

# remove duplicates
out = {k: list(dict.fromkeys(x for x in v if x!=k))
       for k, v in out.items()}

Output:

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

图法

或者您可能想使用图表来解决这个问题:

import networkx as nx

G = nx.from_edgelist(l)

out = {(x:=list(g))[0]: x[1:] for g in nx.connected_components(G)}

Output:

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

图形:

在此处输入图像描述

正如评论中所说,您似乎想找到给定关系的等价类。

ecs = []
for a, b in data:
    a_ec = next((ec for ec in ecs if a in ec), None)
    b_ec = next((ec for ec in ecs if b in ec), None)
    if a_ec:
        if b_ec:
            # Found equivalence classes for both elements, everything is okay
            if a_ec is not b_ec:
                # We only need one of them though
                ecs.remove(b_ec)
                a_ec.update(b_ec)
        else:
            # Add the new element to the found equivalence class       
            a_ec.add(b)
    else:              
        if b_ec:
            # Add the new element to the found equivalence class
            b_ec.add(a)
        else:                                                   
            # First time we see either of these: make a new equivalence class 
            ecs.append({a, b})

# Extract a representative element and construct a dictionary
out = {
    ec.pop(): ec
    for ec in ecs
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM