Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 返回累积和等于输入值的所有可能的键组合_Python_Dictionary - Fatal编程技术网

Python 返回累积和等于输入值的所有可能的键组合

Python 返回累积和等于输入值的所有可能的键组合,python,dictionary,Python,Dictionary,对于inputdata={“a”:1,“b”:1,“c”:3},我想获得如下的dict {1:[[“a”],[“b”], 2:[“a”,“b”], 3:[“c”], 4:[“a”,“c”],[“b”,“c”], 5:[“a”、“b”、“c”]] 其中键是输入字典中所有可能值的累积和,对应值是所有键的列表,使累积和成为可能 这里的困难在于可能有多个解决方案来获得相同的累积和(上面的1就是一个例子)。现在我知道我能做到 {v:list(data.keys())[:idx+1]表示v,idx在zip

对于input
data={“a”:1,“b”:1,“c”:3}
,我想获得如下的dict

{1:[[“a”],[“b”],
2:[“a”,“b”],
3:[“c”],
4:[“a”,“c”],[“b”,“c”],
5:[“a”、“b”、“c”]]
其中键是输入字典中所有可能值的累积和,对应值是所有键的列表,使累积和成为可能

这里的困难在于可能有多个解决方案来获得相同的累积和(上面的
1
就是一个例子)。现在我知道我能做到

{v:list(data.keys())[:idx+1]表示v,idx在zip中(np.cumsum(list(data.values())),range(len(data))}
但这种方法并没有给出我想要的完整解决方案。具体地说,对于输入
数据
,我只能得到

{1:['a'],
2:[a'、[b'],
5:[a',b',c']}
数据中存在更多重复项时,问题可能会变得更难解决


我想知道这个问题是否有好的解决方案(从我的计算理论课程来看,这个问题似乎是NP完全问题)。

您可以使用递归生成器函数获取字典键的所有组合,并使用
集合。defaultdict
根据它们产生的和对组合进行分组:

from collections import defaultdict
data = {"a": 1, "b": 1, "c": 3}
def to_sum(d, c = []):
   if c:
      yield c
   if len(d) > len(c):
      yield from [i for b in data for i in to_sum(d, c+[b]) if b not in c]

result = defaultdict(set)
for i in to_sum(data):
   result[sum(data[j] for j in i)].add(tuple(sorted(i)))

final_result = {a:list(map(list, b)) for a, b in result.items()}
输出:

{1: [['b'], ['a']], 2: [['a', 'b']], 5: [['a', 'b', 'c']], 4: [['b', 'c'], ['a', 'c']], 3: [['c']]}

您的问题与
数据的类型有关。具体来说,电源组不包括空组。我们可以使用标准库中的
itertools
来帮助我们

from collections import defaultdict
from itertools import chain, combinations

def nonempty_powerset(data):
    # adapted from the powerset recipe
    # at https://docs.python.org/3/library/itertools.html
    # start the range from 1 to exclude the empty set
    return chain.from_iterable(combinations(data, r) for r in range(1, len(data) + 1))

def get_subset_sums(data):
    output = defaultdict(list)
    for subset in nonempty_powerset(data):
        # subset is a tuple of strings, if you want lists we need to convert them
        output[sum(data[item] for item in subset)].append(list(subset))
    # convert to a regular dict
    return dict(output)

print(get_subset_sums({"a": 1, "b": 1, "c": 3}))

运行时应该在
O(N*2**N)
中,其中
N=len(data)
,这对于涉及电源组的东西来说非常合理。也许我错过了一个numpy方法,它可以帮助您实现这一点,但除此之外,我认为这相当接近于最佳状态。

您看过iTertools函数了吗?这个问题可能会有所帮助-我认为它的运行时间是
O(N*log(N)*N**N)
其中
N=len(data)