Python sorted lambda function returning a boolean

Viewed 590

So, I have a list of names, and I'm trying to sort the list such that the names that start with a vowel are positioned first within the list and then those that don't start with a vowel are then positioned after them and sorted alphabetically.

To do this, I wrote the following code, however, the result is not what I expected:

a = ["anna", "ollie", "tim", "bob", "trevor", "susan"]
print(sorted(a, key=lambda x: (x[0] in 'aeiou', x)))

Outcome:

['bob', 'susan', 'tim', 'trevor', 'anna', 'ollie']

I thought based on my code, the names: "anna" and "ollie" should be positioned first, and then the rest of the names since these two names would return true for the first part of my lambda function.

I'd appreciate it if someone can explain why I'm getting this result and what I need to do in order to get my desired outcome.

Thanks!!

2 Answers

The reason is that:

x[0] in 'aeiou' 

returns 1 (or True) for ['anna', 'ollie'] and 0 (or False) for the rest. So 0 < 1, hence the output.

Do this instead:

print(sorted(a, key=lambda x: (x[0] not in 'aeiou', x)))

Output

['anna', 'ollie', 'bob', 'susan', 'tim', 'trevor']

For an explanation in comparisons, check the documentation, the quote below is from there:

Tuples and lists are compared lexicographically using comparison of corresponding elements. This means that to compare equal, each element must compare equal and the two sequences must be of the same type and have the same length.

Also for the behavior of Boolean values I suggest, the following link, quoting:

Boolean values are the two constant objects False and True. They are used to represent truth values (although other values can also be considered false or true). In numeric contexts (for example when used as the argument to an arithmetic operator), they behave like the integers 0 and 1, respectively.

When you are returning a boolean value, in python it corresponds True == 1, False == 0. So now when you sort your array, 0 is less than 1. That's why your are getting "anna" and "ollie" positioned last and rest of the names first.

Related