1

Is there a cool way to traverse the dict recursively to get all the combination of the sum(values):

I have a dict {a: 10, b: 20, c:30}

I want to find all the unique combinations of twos and threes (Sum of the Values):

e.g. twos

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

similarly for threes:

60 # 10 + 20 + 30
3
  • What do you mean by "recursively"? Do you mean that the solution must involve recursive programming, or that it must support dicts that themselves contain other dicts? Commented May 7, 2014 at 19:42
  • Wanted to traverse the same dict to sum the combination of the values. E.g. Something that I would have done in a using a for loop : (For i in range (0,2): for j in range (i,2)) Commented May 7, 2014 at 19:44
  • @userDSSR, my answer uses loops that create a powerset of all combinations up to the len of the dict values. Commented May 7, 2014 at 20:36

5 Answers 5

3

For the example input you have given, you can use a combination of map, sum, and itertools.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))

Or, in 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))))

prints:

[40, 30, 50]
[60]
Sign up to request clarification or add additional context in comments.

2 Comments

This probably works fine. I got an error.. <map object at 0x00B9EF30> <map object at 0x00B9EF30> for the above statements. I am using Python 3.4.
That's funny, you should get a syntax error in Python 3.4. I'll update the answer.
2

You can use itertools.combinations to get all the combinations and then sum the results.

E.g.

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

Comments

1

You could use itertools as follows:

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

4 Comments

Thanks. Liked the way to get keys and values.
@userDSSR, this does not even answer your question
It worked. I just had to change itertools.combinations(d,3) to get the combination for 3's. result = [mydict[x] + mydict[y] + mydict[z] for x, y, z in itertools.combinations(d, 3)]
@userDSSR, "I want to find all the unique combinations of twos and threes" "and" being the operative word.
0

Note: the solutions using combinations above are better! But I'll keep this anyway.

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)

Prints:

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

But probably you want only distinct sums, since addition of integers is commutative. Sets come to the rescue.

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)

Prints:

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

The use of tuple above is needed because set() only takes immutable items, and sorted() returns a mutable list.

1 Comment

this does not add 10 + 20 + 30
0

Power set:

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]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.