【问题标题】:Python - recursive loop within a dictPython - 字典中的递归循环
【发布时间】:2014-05-07 19:39:29
【问题描述】:

有没有一种很酷的方法可以递归地遍历dict来得到sum(values)的所有组合:

我有一个字典{a: 10, b: 20, c:30}

我想找出所有三三两两的唯一组合(值的总和):

例如两个

30  # 10 + 20
40  # 10 + 30
50  # 20 + 30

同样适用于三人组:

60 # 10 + 20 + 30

【问题讨论】:

  • “递归”是什么意思?你的意思是解决方案必须涉及递归编程,还是必须支持本身包含其他字典的字典?
  • 想要遍历同一个dict来求和值的组合。例如。我在使用 for 循环时会做的事情:(For i in range (0,2): for j in range (i,2))
  • @userDSSR,我的回答使用循环创建所有组合的幂集,直到 dict 值的 len。

标签: python recursion dictionary


【解决方案1】:

对于您给出的示例输入,您可以使用mapsumitertools.combinations 的组合:

d = {'a': 10, 'b': 20, 'c':30}

import itertools
print map(sum, itertools.combinations(d.values(), 2))
print map(sum, itertools.combinations(d.values(), 3))

或者,在 Python3 中:

d = {'a': 10, 'b': 20, 'c':30}

import itertools
print(list(map(sum, itertools.combinations(d.values(), 2))))
print(list(map(sum, itertools.combinations(d.values(), 3))))

打印:

[40, 30, 50]
[60]

【讨论】:

  • 这可能工作正常。我得到一个错误.. 对于上述语句。我正在使用 Python 3.4。
  • 这很有趣,您应该在 Python 3.4 中遇到语法错误。我会更新答案。
【解决方案2】:

您可以使用itertools.combinations 获取所有组合,然后对结果求和。

例如

from itertools import combinations

mydict = {'a': 10, 'b': 20, 'c':30}
twos = [sum(c) for c in combinations(mydict.values(), 2)]
threes = [sum(c) for c in combinations(mydict.values(), 3)]
print twos
print threes

【讨论】:

    【解决方案3】:

    您可以按如下方式使用itertools

    import itertools
    mydict = {'a': 10, 'b': 20, 'c':30}
    result = [mydict[x] + mydict[y] for x, y in itertools.combinations(d, 2)]
    

    【讨论】:

    • 谢谢。喜欢获取键和值的方式。
    • @userDSSR,这甚至不能回答你的问题
    • 成功了。我只需要更改 itertools.combinations(d,3) 即可获得 3 的组合。结果 = [mydict[x] + mydict[y] + mydict[z] for x, y, z in itertools.combinations(d, 3)]
    • @userDSSR, "我想找到三三两两的所有独特组合" "and" 是有效词。
    【解决方案4】:

    注意:上面使用combinations的解决方案更好! 但无论如何我都会保留它。

    from itertools import permutations
    data = {'a': 10, 'b': 20, 'c':30}
    
    for key_perm in permutations(data.keys(), 2):
      print ' + '.join(key_perm), '=', sum(data[k] for k in key_perm)
    

    打印:

    a + c = 40
    a + b = 30
    c + a = 40
    c + b = 50
    b + a = 30
    b + c = 50
    

    但可能你只想要不同的和,因为整数的加法是可交换的。套装来救援。

    for key_perm in set(tuple(sorted(perm)) for perm in permutations(data.keys(), 2)):
      print ' + '.join(key_perm), '=', sum(data[k] for k in key_perm)
    

    打印:

    b + c = 50
    a + b = 30
    a + c = 40
    

    上面需要使用tuple,因为set()只接受不可变的项目,而sorted()返回一个可变的list

    【讨论】:

    • 这不加 10 + 20 + 30
    【解决方案5】:

    电源组:

    d={'a': 10, 'b': 20, 'c':30}
    def power_set(items):
        n = len(items)
        for i in xrange(2**n):
            combo = []
            for j in xrange(n):
                if (i >> j) % 2 == 1:
                    combo.append(items[j])
            yield combo
    data= [sum(x) for x in  list(power_set(d.values())) if len(x)>1]
    In [10]: data
    Out[10]: [40, 30, 50, 60]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多