I'm having trouble understanding sorting by key using lambda function.
l = ['mix', 'xyz', 'apple', 'xanadu', 'aardvark']
print('Unsorted:%s' % l)
lSorted = sorted(l)
print('Sorted:%s' % lSorted)
lFinalSort = sorted(lSorted, key=lambda a : 'x' != a[0])
print('Final Sort:%s' % lFinalSort)
lFinalSort = sorted(lSorted,
Is the list we're sorting. key=
is the special 'contingency' we're sorting by. lambda a :
is a temporary function with a
being an arbitrary argument. 'x' != a[0]
This is the part that doesn't make sense on how it prioritizes sorting by 'x'
first. If 'x'
does not equal the first letter in the item we're sorting, sort by it?
In that case, why doesn't:
lFinalSort = sorted(lSorted, key=lambda a : 'd' in a)
sort by all words that contain 'd'
first?
CodePudding user response:
I think what you are asking to do is sort by a virtual tuple:
l = ['mix', 'xyz', 'apple', 'xanadu', 'aardvark']
print('Unsorted:%s' % l)
lSorted = sorted(l)
print('Sorted:%s' % lSorted)
lFinalSort = sorted(l, key=lambda a : ('x' != a[0], a))
print('Final Sort:%s' % lFinalSort)
This gives you:
Unsorted:['mix', 'xyz', 'apple', 'xanadu', 'aardvark']
Sorted:['aardvark', 'apple', 'mix', 'xanadu', 'xyz']
Final Sort:['xanadu', 'xyz', 'aardvark', 'apple', 'mix']
CodePudding user response:
The key
argument in the sorted
takes a function that returns a value that has a number behind it. The key function works as exactly as described in the documentations:
The value of the key parameter should be a function (or other callable) that takes a single argument and returns a key to use for sorting purposes. This technique is fast because the key function is called exactly once for each input record.
It might come to mind that *What would happen if we wanted to sort a list of strings?". In such case, it will sort the list in the order of the alphabet. You can think of this as if the alphabets are numbers. For example A is 1, B is 2, ..., a is 27, b is 28 and so on.
In the case of booleans, note that python assigns some of the boolean values to other values of other types (see this). Therefore, False
values are equal to zero
and True
values are equal to 1
.
And why does:
lFinalSort = sorted(lSorted, key=lambda a : 'd' in a[0])
bring 'aardvark' to the front but leaves 'xanadu' second to last?
Actually, it doesn't. This line does not do anything. It has the exact same values as the lSorted
variable since the lambda
function returns False(read 0
) for all of the elements.
Also, note that if you want to sort based on the multiple conditions, you can do something like:
sorted(lSorted, key=lambda a : (a[1], a[2]))
This will first sort your list based on the second character of each element and if there is any case that two elements have same second character, then it goes to next character(third one) and sort them based on it.