-1

I was looking into this question about sorting a list of lists with multiple criteria (element 0 descending and element 1 ascending) .

L = [['a',1], ['a',2], ['a',3], ['b',1], ['b',2], ['b',3]]
L.sort(key=lambda k: (-k[0], k[1]), reverse=True)

is there a way to make it work when the first or the second element is a string?

Community
  • 1
  • 1
Bob
  • 553
  • 1
  • 5
  • 10

2 Answers2

4

It is simple, just use -ord for your strings:

L.sort(key=lambda k: (-ord(k[0]), k[1]), reverse=True)

Output:

In [1]: L = [['a',1], ['a',2], ['a',3], ['b',1], ['b',2], ['b',3]]

In [2]: L.sort(key=lambda k: (-ord(k[0]), k[1]), reverse=True)

In [3]: L
Out[3]: [['a', 3], ['a', 2], ['a', 1], ['b', 3], ['b', 2], ['b', 1]]

You can get the exact same result by not using reverse and negating the int values:

L = [['a',1], ['a',2], ['a',3], ['b',1], ['b',2], ['b',3]]

L.sort(key=lambda k: (k[0], -k[1]))

print(L)
[['a', 3], ['a', 2], ['a', 1], ['b', 3], ['b', 2], ['b', 1]]

So for a mixture of strings and ints you don't actually need cmp, ord or anything other negating the int values.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
1

As you want to reverse the sort order for the second string, using the key function won't work. However, using the cmp function will work:

L.sort(cmp=lambda x, y: cmp(x[0], y[0]) or -cmp(x[1], y[1]))
llogiq
  • 13,815
  • 8
  • 40
  • 72