将列表组合到期望列表

时间:2017-04-25 21:19:38

标签: python

如果我有以下列表词典:

{1: [2], 2: [1, 3, 5], 3: [2, 4], 4: [3, 7], 5: [2, 6], 6: [5], 7: [8, 4], 8: [7]}

我想知道我需要一整套的钥匙:

[1,2,3,4,5,6,7,8]

使用最少数量的键。对于这个特殊问题,例如它将是:

keys needed: [2,5,7]

虽然订单无关紧要但我想尽可能少地使用密钥。有没有一种简单的方法来测试我的答案是否是最短的答案?

3 个答案:

答案 0 :(得分:1)

以下是使用itertools.combinations

的强力解决方案
from itertools import combinations
data = {1: [2], 2: [1, 3, 5], 3: [2, 4], 4: [3, 7], 5: [2, 6], 6: [5], 7: [8, 4], 8: [7]}
desired_set = set([1, 2, 3, 4, 5, 6, 7, 8])

n = len(data)

all_values = set(x for values in data.values() for x in values)
if all_values.issuperset(desired_set):
    print("There must be a solution...")
    n = len(data)
    for i in range(0, n + 1):
        for combination in combinations(data, i):
            values = set(x for key in combination for x in data[key])
            if values.issuperset(desired_set):
                print("FOUND!")
                print("Keys needed : %r" % list(combination))
                print("Values : %r" % list(values))
                quit()
else:
    print "Not possible. Not even trying"

输出:

FOUND!
Keys needed : [2, 4, 5, 7]
Values : [1, 2, 3, 4, 5, 6, 7, 8]

最糟糕的情况是O(2**n),所以不要在大数据集上使用它!

请注意,您需要4作为获取7值的关键。

答案 1 :(得分:0)

如果您只想按顺序键,可以直接在字典上调用sorted()。

some_dict = {1: [2], 2: [1, 3, 5], 3: [2, 4], 4: [3, 7], 5: [2, 6], 6: [5], 7: [8, 4], 8: [7]}

keys = sorted(some_dict)
print(keys)

[1, 2, 3, 4, 5, 6, 7, 8]

另一方面,如果您希望按字母顺序排列字典中的所有唯一VALUES,则应对一组进行排序。

values = sorted({x for key in some_dict for x in some_dict[key]})
print(values)

[1, 2, 3, 4, 5, 6, 7, 8]

我不知道你为什么要使用尽可能短的键,但你可以这样做。

wanted = set(range(1, 9))
seen = set()
for key in some_dict:
    seen |= set(some_dict[key])
    if seen == wanted:
        break

答案 2 :(得分:0)

如果你的意思是价值而不是关键,那你就去吧。

d = {1: [2], 2: [1, 3, 5], 3: [2, 4], 4: [3, 7], 5: [2, 6], 6: [5], 7: [8, 4], 8: [7]}
#get the values from all elements and use a set to remove duplicate and then use sum to flatten the list.
list(set(sum(d.values(),[])))
Out[806]: [1, 2, 3, 4, 5, 6, 7, 8]