Hacker News new | ask | show | jobs
by tigershark 3105 days ago
No idea about C++ but in C# seems quite more readable (and flexible)

    someList.OrderByDescending(x => x.weight).ThenByDescending(x => x.Name);
It's quite similar to expressing the concept in English, certainly more than using list comprehension in Python.

And how would you order it in Python by ascending on the first field and descending on the second using list comprehension?

1 comments

That's not the same thing, you've sorted a list of objects, we're looking for a list of tuples of `weight, name`)

In answer to your question though,

    sorted(((k.weight, k.name) for k in some_list), key=lambda x: (-x[0], x[1]), reverse=True)
appears to work. This does use a non-obvious trick, but being more explicit is a smidge difficult, since the key function is called only n times, as opposed to O(nlogn) in the C# example.

Alternatively, you can use

    sorted(sorted(((k.weight, k.name) for k in some_list), key=lambda x: x[1], reverse=True), key=x[0])
Which is more like the original example, and if you're doing it in place, you get

    outs = [k.weight, k.name) for k in some_list]
    outs.sort(key=lambda x: x[1], reverse=True)
    outs.sort(key=lambda x: x[0])
Python's builtin sort is timsort, so despite sorting the list twice, this will still run in approximately NlogN comparisons, not 2NlogN.

You could also manually define a custom comparator, ie

   lambda s, o: (s[0] > o[0] * 10 + s[1] < o[1])
and pass it to `functools.cmp_to_key`.