-2

I have a question similar to that one I asked last week: "Sorting dict items by key, beyond alphanumeric sorting"

The problem is identic, but now the keys of my dict are simply integers:

>>>lis_nodiz = list(nodiz.items()) #list of dict items as tuples
[(2, 316),
(3, 66),
(4, 37),
(5, 15),
(6, 10),
(7, 4),
(8, 3),
(9, 1),
(10, 2),
(11, 1),
(12, 1),
(45, 1),
(109, 1),
(16, 1),
(126, 1)]

As you would have guess I'm searching for this ordered list of tuples:

[(2, 316),
(3, 66),
(4, 37),
(5, 15),
(6, 10),
(7, 4),
(8, 3),
(9, 1),
(10, 2),
(11, 1),
(12, 1),
(16, 1),
(45, 1),
(109, 1),
(126, 1)]

I have tried to reuse the "key_func" Padraic Cunningham suggested me, unfortunately this function seems to work only with string type dict keys:

def key_func(x):
"""'a0p12' -> (0, 12)"""
return tuple(int("".join(v)) for k,v in groupby(x[0], key=str.isdigit) if k)

>>>lis_nodiz_od = sorted(nodiz.items(), key=key_func)
TypeError: expected string or buffer

How to modify the function, or how can I do in another way to get my purpose? I would appreciate very much if somebody explains how the "key_func" really works, and the correct modifications to do in order to make it work with integers; this way I will understand more about Python programming I hope, and not only solve my problem of today! Thanks you all very much!

Community
  • 1
  • 1
mik.ferrucci
  • 121
  • 1
  • 2
  • 13
  • As a defence for the remain of this question, I know the question had been asked before; anyway it seems to me that the part of the question regarding the key_func is original and not asked before. So in definitive my question had not fully asked and answerded before.. up to you! – mik.ferrucci Oct 26 '16 at 14:33

2 Answers2

2

Call sorted() or list.sort() as:

# sorted(): Creates new list with sorted order
>>> sorted(lis_nodiz)  
[(2, 316), (3, 66), (4, 37), (5, 15), (6, 10), (7, 4), (8, 3), (9, 1), (10, 2), (11, 1), (12, 1), (16, 1), (45, 1), (109, 1), (126, 1)]

# list.sort(): sort the existing  list
>>> lis_nodiz.sort()
>>> lis_nodiz
[(2, 316), (3, 66), (4, 37), (5, 15), (6, 10), (7, 4), (8, 3), (9, 1), (10, 2), (11, 1), (12, 1), (16, 1), (45, 1), (109, 1), (126, 1)]

where lis_nodiz is list of tuples as mentioned in question.

Note: No need to specify key here. By default does lexicographical sort on 0th index; in case of same value, sorts on 1st index.

Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
  • 2
    Note that the key function is only necessary if you want the sort to be stable on the second element; tuples already sort lexicographically on their elements from left to right. Also, `operator.itemgetter(0)` should be more efficient than a user-defined function. – chepner Oct 26 '16 at 14:07
  • @chepner: Thanks for the valuable piece of information – Moinuddin Quadri Oct 26 '16 at 14:08
  • 1
    Ok, thank both you for your explainations and answers! – mik.ferrucci Oct 26 '16 at 14:14
0

No need to sort with a lambda on the first key: that's the default for a tuple.

>>> sorted(x)
[(2, 316), (3, 66), (4, 37), (5, 15), (6, 10), (7, 4), (8, 3), (9, 1), (10, 2), (11, 1), (12, 1), (16, 1), (45, 1), (109, 1), (126, 1)]

It will automatically sort on the first member, and if they are equal will sort by the second member, etc.

brianpck
  • 8,084
  • 1
  • 22
  • 33