4

I have a dictionary with tuple as its key, like:

d={('w1','u1'):3,('w1','u2'):8,('w2','u1'):1,('w1','u3'):11,('w2','u3'):6}

Now I want to gather all items for each 'w', i.e. the first element in the keys:

'w1' :  ('w1','u1'):3 ('w1','u2'):8 ('w1','u3'):11 -------
'w2' :  ('w2','u1'):1 ('w2','u3'):6 

then sort each row by the values to get:

'w1' : 'u3':11 'u2':8 'u1':3 -------
'w2' :  'u3':6 'u1':1

Can anybody give me some hint to do it? Thanks

TerryA
  • 58,805
  • 11
  • 114
  • 143
  • By "gather" you mean to create a nested dictionary? i.e. `'w1': {('w1', 'u1'): 3, ('w1', 'u2'): 8, ...}`? By they way: I don't see the reason to keep `'w1'` in the nested dictionary. Doing `'w1': {'u1': 3, 'u2': 8, ...}` gives exactly the same information. – Bakuriu Jul 13 '13 at 12:53

2 Answers2

3

This gives what you want, sorted. But it's not in a dictionary at the end, since you can't sort a dictionary.

d={('w1','u1'):3,('w1','u2'):8,('w2','u1'):1,('w1','u3'):11,('w2','u3'):6}

d2 = {}

for (w,u) , value in d.items():
    if w not in d2:
        d2[w] = [(u,value)]
    else:
        d2[w].append((u, value))


for key, values in d2.items():
    print key, ":\t", sorted(values, key=lambda x: -x[1]), "\n"

which gives:

w2 :    [('u3', 6), ('u1', 1)] 

w1 :    [('u3', 11), ('u2', 8), ('u1', 3)] 
will
  • 10,260
  • 6
  • 46
  • 69
2

Given the final dict you are after, it doesn't seem to me you need to sort. Just iterate through the key-value pairs, and rearrange them into a new dict:

d = {('w1', 'u1'): 3, ('w1', 'u2'): 8, ('w2', 'u1'): 1, ('w1', 'u3'): 11,
     ('w2', 'u3'): 6}
result = {}
for (w, u), val in d.iteritems():
    result.setdefault(w, {})[u] = val
print(result)

yields

{'w2': {'u1': 1, 'u3': 6}, 'w1': {'u1': 3, 'u3': 11, 'u2': 8}}
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677