Get a list of tuples (or lists) where the lists with the same elements are grouped?

时间:2019-03-17 22:51:23

标签: python

I have a dictionary in python with several lists, and what I try to do is get a list of tuples (or lists) where the lists are grouped with the same elements regardless of whether they are ordered. For example:

dict_1 = {
    "pv_0": [1, 2, 3, 4, 5],
    "pv_1": [2, 4, 6, 8, 10],
    "pv_2": [1, 3, 5, 7, 9],
    "pv_3": [3, 4, 1, 2, 5],
    "pv_4": [2, 3, 4, 5, 6],
    "pv_5": [3, 4, 5, 6, 2],
    "pv_6": [1, 2, 3, 5, 4],
    "pv_7": [5, 9, 7, 3, 1],
    "pv_8": [2, 4, 6, 8, 10],
    "pv_9": [1, 3, 5, 6, 7],
}

I wish to obtain the following result:

Result = [
    ("pv_0", "pv_3", "pv_6"),
    ("pv_2", "pv_7"),
    ("pv_1", "pv_8"),
    ("pv_4", "pv_5"),
    ("pv_9"),
]

How do I solve this problem?

2 个答案:

答案 0 :(得分:0)

据我所知,您想要一个键元组,其中每个值都相同。

def get_matching_keys(data: dict) -> list: 
    # first, make everything a set
    for key in data: 
        data [key] = set (data [key])  # makes order irrelevant
    results = []
    duplicates = []
    for key, value in data.items():
        if key in duplicates: continue  # we already did this
        result = [key]
        duplicates.append (key)
        for key2, value2 in data.items():
            if key == key2: continue  # skip the same key
            else: 
                if value == value2: 
                    result.append (key2)
                    duplicates.append (key2)  # make sure we don't do it again
        results.append (result)
    return results

答案 1 :(得分:0)

from operator import itemgetter
from itertools import groupby

# create a new dictionary where the value is a hashed immutable set
d = {k: hash(frozenset(v)) for k, v in dict_.items()}

{'pv_0': -3779889356588604112,
 'pv_1': 2564111202014126800,
 'pv_2': 777379418226018803,
 'pv_3': -3779889356588604112,
 'pv_4': 8713515799959436501,
 'pv_5': 8713515799959436501,
 'pv_6': -3779889356588604112,
 'pv_7': 777379418226018803,
 'pv_8': 2564111202014126800,
 'pv_9': -6160949303479789752}

first = itemgetter(0) # operator to grab first item of iterable
second = itemgetter(1) # operator to grab second item of iterable

[list(map(first, v)) for _, v in groupby(sorted(d.items(), key=second), key=second)]

[['pv_9'],
 ['pv_0', 'pv_3', 'pv_6'],
 ['pv_2', 'pv_7'],
 ['pv_1', 'pv_8'],
 ['pv_4', 'pv_5']]

最终的列表理解会从字典中获取所有键/值对,并按值对它们进行排序。然后,它将其从itertools传递到groupby函数,并告诉它按字典的值分组。然后将其输出输入到map函数,该函数从组中的每对中获取第一项,这将是对应的键。