在元组列表中查找重复项Python

2024-06-25 23:08:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我想从下面给出的匹配项中找到匹配项名单。我的列表可能非常大。在

元组“N1_10”中的第一个项被复制并与另一个数组中的另一个项匹配

列表中第一个数组中的元组('N1_10', 'N2_28')
列表中第二个数组中的元组('N1_10', 'N3_98')

ListA  = [[('N1_10', 'N2_28'), ('N1_35', 'N2_44')],
          [('N1_22', 'N3_72'), ('N1_10', 'N3_98')],
          [('N2_33', 'N3_28'), ('N2_55', 'N3_62'), ('N2_61', 'N3_37')]]

我想要的输出是

输出--> 密钥将进入同一元组]

如果你们认为,改变ListA的数据结构是更好的选择,请随时提出建议! 谢谢你的帮助!在

简化版

列表A=[(A,x),(b,k),(c,l),(d,m),[(e,d),(A,p),(g,s)],[…],[…]…]

期望输出-->;[(a,x,p),(b,k),(c,l),(d,m,e),(g,s)…]


Tags: gt数据结构列表密钥数组建议元组名单
3条回答
tupleList = [(1, 2), (3, 4), (1, 4), (3, 2), (1, 2), (7, 9), (9, 8), (5, 6)]

newSetSet = set ([frozenset (aTuple) for aTuple in tupleList])
setSet = set ()

while newSetSet != setSet:
    print '*'
    setSet = newSetSet
    newSetSet = set ()
    for set0 in setSet:
        merged = False
        for set1 in setSet:
            if set0 & set1 and set0 != set1:
                newSetSet.add (set0 | set1)
                merged = True
        if not merged:
            newSetSet.add (set0)

        print [tuple (element) for element in setSet]
        print [tuple (element) for element in newSetSet]
        print 

print [tuple (element) for element in newSetSet]

# Result:  [(1, 2, 3, 4), (5, 6), (8, 9, 7)]

输出顺序重要吗?这是我能想到的最简单的方法:

ListA  = [[('N1_10', 'N2_28'), ('N1_35', 'N2_44')],[('N1_22', 'N3_72'), ('N1_10', 'N3_98')],
            [('N2_33', 'N3_28'), ('N2_55', 'N3_62'), ('N2_61', 'N3_37')]]

idx = dict()

for sublist in ListA:
    for pair in sublist:
        for item in pair:
            mapping = idx.get(item,set())
            mapping.update(pair)
            idx[item] = mapping 
            for subitem in mapping:
                submapping = idx.get(subitem,set())
                submapping.update(mapping)
                idx[subitem] = submapping


for x in set([frozenset(x) for x in idx.values()]):
    print list(x)

输出:

^{pr2}$

更新:重读问题后,您似乎在尝试创建等价类,而不是收集键的值。如果

[[(1, 2), (3, 4), (2, 3)]]

应该变成

^{pr2}$

,然后需要将输入解释为图形并应用连接组件算法。您可以将数据结构转换为adjacency list表示,并使用广度优先或深度优先搜索遍历它,或者遍历列表并构建disjoint sets。无论哪种情况,你的代码都会突然涉及大量与图相关的复杂性,而且很难根据输入的顺序提供任何输出排序保证。以下是基于广度优先搜索的算法:

import collections

# build an adjacency list representation of your input
graph = collections.defaultdict(set)
for l in ListA:
    for first, second in l:
        graph[first].add(second)
        graph[second].add(first)

# breadth-first search the graph to produce the output
output = []
marked = set() # a set of all nodes whose connected component is known
for node in graph:
    if node not in marked:
        # this node is not in any previously seen connected component
        # run a breadth-first search to determine its connected component
        frontier = set([node])
        connected_component = []
        while frontier:
            marked |= frontier
            connected_component.extend(frontier)

            # find all unmarked nodes directly connected to frontier nodes
            # they will form the new frontier
            new_frontier = set()
            for node in frontier:
                new_frontier |= graph[node] - marked
            frontier = new_frontier
        output.append(tuple(connected_component))

但是,不要只是在没有理解的情况下复制它;要理解它在做什么,或者编写自己的实现。你可能需要能够维持这个。(我会使用伪代码,但Python实际上已经和伪代码一样简单了。)

如果我对您问题的最初解释是正确的,并且您的输入是要聚合的键值对的集合,那么我的原始答案如下:

原始答案

import collections

clusterer = collections.defaultdict(list)

for l in ListA:
    for k, v in l:
        clusterer[k].append(v)

output = clusterer.values()

defaultdict(list)是一个dict,它自动创建一个list作为任何不存在的键的值。循环遍历所有元组,收集与同一个键匹配的所有值,然后从defaultdict创建一个(key,value_list)对列表。在

(此代码的输出与您指定的格式不完全相同,但我相信这种格式更有用。如果你想改变形式,那应该是件简单的事。)

相关问题 更多 >