Index out of range when using lambda
The list
list(zip(*tuples))
in your lambda
function is not a constant one - it evaluates again and again in every sorting step - every time when your lambda
function is called.
1st sorting step is OK - the lambda
function is exactly what you wanted. But then raises a problem.
The tuples
list is during sorting in an unstable state, maybe empty, maybe something else - the sorting algorithm has freedom in it. Its only duty is so that the sorted list will be in the right state after performing the complete sort.
2nd sorting step evaluates the value of your lambda
function on the basis of this unstable list - who knows its current value?
So using sorted list itself in the key
function is not a very happy decision.
If you used a vanilla function and printed the list while it is being sorted, you'll notice the list is cleared out during the sort operation (AFAIK this applies to CPython). There isn't an index zero for an empty list:
def f(x):
print (tuples)
return ...
tuples.sort(key=f ,reverse=True)
[]
[]
[]
[]
[]
[]
[]
[]
[]
A peek into the CPython source leaves us with a useful comment that explains this behaviour:
static PyObject *
list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
{
...
/* The list is temporarily made empty, so that mutations performed
* by comparison functions can't affect the slice of memory we're
* sorting (allowing mutations during sorting is a core-dump
* factory, since ob_item may change).
*/
...
}
To your original problem, instead of calling list.count
repeatedly, which is very inefficient, you can build a counter and then use that for sorting:
from collections import Counter
c = Counter([x[0] for x in tuples])
tuples.sort(key=lambda x: c[x[0]], reverse=True)