Reputation: 133
I am trying to sort a list, move all 0 to the end of list. example: [0,1,0,2,3,0,4]->[1,2,3,4,0,0,0]
and I see someone code it in 1 line
list.sort(cmp=lambda a,b:-1 if b==0 else 0)
But I don't understand what inside the parentheses mean.
Could anyone tell me? Thank you.
Upvotes: 9
Views: 31106
Reputation: 5665
You should answer yourself and this is plan for make actions for study:
The ternary expression description is available here:
You can find a lot of expression description in that document:
https://docs.python.org/3/reference/expressions.html
Q: What does lambda mean?
Please spend just 5 days and read a Tutorial about Python language, which is a fork of the original Gvinno Van Rossum book.
https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions
Upvotes: -1
Reputation: 6511
>>> sorted(l, key=lambda x:str(x) if x == 0 else x)
[1, 3, 4, 8, 0, 0, 0]
Guess what's happening here? I am exploiting the fact that, as a preference, python will pick up integers first, then strings. SO I converted 0 into '0'.
Here's the proof.
>>> ll = [3,2,3, '1', '3', '0']
>>> sorted(ll)
[2, 3, 3, '0', '1', '3']
Upvotes: 0
Reputation: 26022
Sort a list according to the normal comparison:
some_list.sort()
Supply a custom comparator:
some_list.sort(cmp=my_comparator)
x = lambda a, b: a - b
# is roughly the same as
def x(a, b):
return a - b
value = truthy_case if condition else otherwise
# is roughly the same as
if condition:
value = truthy_case
else:
value = otherwise
list.sort(cmp=lambda a,b:-1 if b==0 else 0)
itself:Now, the condition in the comparator is whether b==0
, if so indicate that b
has a bigger value than a
(the sign of the result is negative), otherwise indicate that the values compare the same (the sign is zero).
Whilst Python's list.sort()
is stable, this code is not sane, because the comparator needs to test a
, too, not only b
. A proper implementation would use the key
argument:
some_list.sort(key=lambda a: 0 if a == 0 else -1)
list.sort(cmp=...)
implementation:If you want to use list.sort(cmp=...)
(you don't) or if you are just curious, this is a sane implementation:
some_list.sort(cmp=lambda a, b: 0 if a == b else
+1 if a == 0 else
-1 if b == 0 else 0)
In Py3.0, the
cmp
parameter was removed entirely (as part of a larger effort to simplify and unify the language, eliminating the conflict between rich comparisons and the__cmp__
methods).
Sorting a list is in O(𝘯 log 𝘯)
. I do not know if for this simple problem the code runs faster, but I wouldn't think so. An O(𝘯)
solution is filtering:
new_list = [x for x in some_list if x != 0]
new_list.extend([0] * (len(some_list) - len(new_list)))
The difference will probably only matter for quite long lists, though.
Upvotes: 17