case-insensitive list sorting, without lowercasing the result?
Solution 1
In Python 3.3+ there is the str.casefold
method that's specifically designed for caseless matching:
sorted_list = sorted(unsorted_list, key=str.casefold)
In Python 2 use lower()
:
sorted_list = sorted(unsorted_list, key=lambda s: s.lower())
It works for both normal and unicode strings, since they both have a lower
method.
In Python 2 it works for a mix of normal and unicode strings, since values of the two types can be compared with each other. Python 3 doesn't work like that, though: you can't compare a byte string and a unicode string, so in Python 3 you should do the sane thing and only sort lists of one type of string.
>>> lst = ['Aden', u'abe1']
>>> sorted(lst)
['Aden', u'abe1']
>>> sorted(lst, key=lambda s: s.lower())
[u'abe1', 'Aden']
Solution 2
>>> x = ['Aden', 'abel']
>>> sorted(x, key=str.lower) # Or unicode.lower if all items are unicode
['abel', 'Aden']
In Python 3 str
is unicode but in Python 2 you can use this more general approach which works for both str
and unicode
:
>>> sorted(x, key=lambda s: s.lower())
['abel', 'Aden']
Solution 3
You can also try this to sort the list in-place:
>>> x = ['Aden', 'abel']
>>> x.sort(key=lambda y: y.lower())
>>> x
['abel', 'Aden']
Solution 4
This works in Python 3 and does not involves lowercasing the result (!).
values.sort(key=str.lower)
Solution 5
In python3 you can use
list1.sort(key=lambda x: x.lower()) #Case In-sensitive
list1.sort() #Case Sensitive
Related videos on Youtube
Comments
-
jamylak almost 2 years
I have a list of strings like this:
['Aden', 'abel']
I want to sort the items, case-insensitive. So I want to get:
['abel', 'Aden']
But I get the opposite with
sorted()
orlist.sort()
, because uppercase appears before lowercase.How can I ignore the case? I've seen solutions which involves lowercasing all list items, but I don't want to change the case of the list items.
-
ady over 5 yearsThis tutorial is very helpful: docs.python.org/3/howto/sorting.html#sortinghowto
-
-
Admin about 12 yearsThank you. I know I should have mentioned this before, but I've heard there's a problem with using this method on a unicode string (Py2). Do you know anything about that?
-
Admin about 12 yearsThey are all unicode. Thanks! One more question, how to do it on a list like this:
[['Aden'], ['abel']]
-
jamylak about 12 yearsDoes each list only have one item? If so just modify it a bit to:
sorted(x,key=lambda i:i[0].lower())
-
Admin about 12 yearsWell, it might have some other stuff as well, which should not be used for sorting though.
-
jamylak about 12 yearsNevermind, it appears i was wrong, the sorting does work for a mix of both string and unicode, i was confused with a previous question where tuples were also included in the sort.
-
IceArdor over 10 yearsThis solution is overkill and unreadable when a one-liner suffices. This might be more acceptable in a language other than Python.
-
Daniel Andersson almost 8 yearsOne can avoid the lambda function roundtrip by (Python 3) using the general
str.lower
function assorted(lst, key=str.lower)
or (Python 2) using thelower
method of thestring
module assorted(lst, key=string.lower)
. One can also usestr.lower
for strings in Python 2, but would then have to useunicode.lower
forunicode
objects, whereasstring.lower
accepts both (which, as you put it, is probably not really a "sane" mode of operation, though). -
matth about 4 yearshowto sorting: docs.python.org/3/howto/sorting.html#key-functions list.sort: docs.python.org/3/library/stdtypes.html#list.sort
-
Enterprise almost 4 yearsThis would not work for a list like ['Z', 'B', 'a', 'b', 'A'], which sorts to ['a', 'A', 'B', 'b', 'Z']. The capital 'B' appears before the lowercase 'b' because Python's sort() and sorted() preserve the original order when strings match. In this case the capital 'B' is considered to match the lowercase 'b' when using casefold. This always happens if you convert case in order to compare: sorted(spam, key=str.lower) or sorted(spam, key=str.upper) or sorted(spam, key=str.casefold).
-
Enterprise almost 4 yearsTry this solution instead: stackoverflow.com/a/1098160/10668287. It will sort ['Aden', 'aden'] correctly as ['aden', 'Aden'].
-
Mike Q about 2 yearsThe biggest issue with this solution is that it violates the rule of using the built-in tested tooling for a home grown solution. It is an interesting response though, I'll give you that.
-
Mike Q about 2 yearsThe biggest issue with this solution is that it violates the rule of using the built-in tested tooling for a home grown solution. It is an interesting response though, I'll give you that.