0

How does one group by partial key, where the key is composed of multiple tuples and we want to group by all of them except the first one. Example:

example = {((0, 0), (0, 2)): (-1, 0), ((2, 0), (0, 2)): (1, 0), ((2, 1), (0, 3)): (1,0)}

End result of group by:

first_group = {((0, 0), (0, 2)): (-1, 0), ((2, 0), (0, 2)): (1, 0)}
second_group = {((2, 1), (0, 3)): (1,0)}

Here the key is length 2 and we only groped by second tuple in key. But if the key the length of 3 (n) tuples:

{((0, 0), (0, 2), (0, 3)): (-2, 0)}

I want it to group by the last two (n-1):

(0, 2), (0, 3)

I have looked at this question but I had no luck to apply itertools.groupby to this structure where they key can be composed of multiple tuples.

ekad
  • 14,436
  • 26
  • 44
  • 46
Jernej Jerin
  • 3,179
  • 9
  • 37
  • 53
  • So you want to recombine the nested tuple `((a,b), (c,d), e, f)` into a grouping key like `((c,d), (e,f))`? Is that the only and exact structure for all the items? – Tim Pietzcker Jan 06 '14 at 09:42
  • Just saw I made a mistake in example of key length 3. It is fixed now. I want to have have groups by all tuples except the first tuple in key. The key can have arbitrary number of tuples. – Jernej Jerin Jan 06 '14 at 09:45

1 Answers1

1

Try this:

import itertools

example = {((0, 0), (0, 2), (0, 3)): (-2, 0),
           ((1, 3), (0, 2), (0, 3)): (-5, 8),
           ((4, 7), (0, 2), (0, 1)): (3, -2)}
keyfunc = lambda x: x[0][1:] # [0] -> key; [1:] -> all-but-first tuple

items = sorted(example.items(), key=keyfunc)

for key, subiterator in itertools.groupby(items, keyfunc):
    # grouped by this
    print(key)
    for subkey, subvalue in subiterator:
        # but these are the actual things that were grouped
        print(subkey, ':', subvalue) 

Results:

((0, 2), (0, 1)) # <- grouped-by
((4, 7), (0, 2), (0, 1)) : (3, -2)
((0, 2), (0, 3)) # <- grouped-by
((0, 0), (0, 2), (0, 3)) : (-2, 0)
((1, 3), (0, 2), (0, 3)) : (-5, 8)

I'm not sure how you were doing this originally, since you didn't post the code you were using to do the grouping, but this ought to do the trick.

senshin
  • 10,022
  • 7
  • 46
  • 59
  • Do you maybe know how to leave out the key from the grouped values? I have modified your example so I get the whole group back in dictionary: `group = dict(subiterator)`. Should I just use second for statement and add one by one into dictionary meanwhile removing key from subkey. – Jernej Jerin Jan 06 '14 at 10:45