Reputation: 4643
I want to sort a string to a list in lexicographic order as
str='aAaBbcCdE'
to
['A','a','a','B','b','C','c','d','E']
but sorted()
gives me this output:
['A','B','C','E','a','a','b','c','d']
How can I sort lexicographically?
Upvotes: 32
Views: 67270
Reputation: 5834
Use the natsort library. Better to use a library than a custom solution found in an online forum which may not be tested for all edge cases.
from natsort import natsorted
natsorted('aAaBbcCdE')
Output:
['A', 'B', 'C', 'E', 'a', 'a', 'b', 'c', 'd']
Upvotes: 0
Reputation: 1045
In case you aren't dealing with a collection of simple strings but would still like to sort by natural sort order rather than lexicographic order:
Suppose you have a collection of object instances that you'd like to sort by a particular attribute and the attribute values can start in either upper or lower case then you can do something like this:
sorted(objects, lambda object: object.attr1.lower())
assuming attr1
is of type string. Why does this work? Because you are converting all the sorting keys into the same case for the purpose of sorting thus defeating lexicographical sorting. Without the use of lower() or upper() would result in lexicographic sort order rather than natural alphabetical sort order.
Upvotes: 0
Reputation: 879681
You could use a 2-tuple for the key:
text='aAaBbcCdE'
sorted(text, key=lambda x: (str.lower(x), x))
# ['A', 'a', 'a', 'B', 'b', 'C', 'c', 'd', 'E']
The first element in the tuple, str.lower(x)
is the primary key (making a
come before B
), while x
itself breaks ties (making A
come before a
).
Upvotes: 17
Reputation: 7
data = input()
data=list(data)
data.sort()
Now the variable "data" will have lexicographically sorte`d input provided.
Upvotes: -1
Reputation: 96266
cmp
was the old way of doing this, now deprecated, but for posterity:
s='aAaBbcCdE'
sorted(s, lambda x,y: cmp(x.lower(), y.lower()) or cmp(x,y))
Upvotes: 4
Reputation: 33397
Do not use lambda functions when there's builtin ones for the job. Also never use the cmp
argument of sorted because it's deprecated:
sorted(s, key=str.lower)
or
sorted(s, key=str.upper)
But that may not keep 'A' and 'a' in order, so:
sorted(sorted(s), key=str.upper)
that will and, by the nature of sorted
the operation will be very fast for almost sorted lists (the second sorted
).
Upvotes: 42