Reputation: 24949
I tried to sort using sorted
dir =["A1","A2","A10","A3"]
sorted(dir)
My expected array is
["A1","A2","A3","A10"]
but actual result is
["A1", "A10", "A2", "A3"]
How to sort array by name in python ?
Upvotes: 2
Views: 5582
Reputation: 2510
To extend this question, I had to sort interface names in a natural way. What makes it a bit more complex is interfaces can go in many flavors... You have the traditional ones such as lo
, eth0
, etc... and some more advanced schemes like enp4s0f1d1
. The solution is to split them based on type, convert numbers to int's and care must be taken to ensure comparison happens on same type.
So I came up with this sort function which should be fairly bulletproof (as long as you give it strings...)
def ethkey(eth):
"""Split an ethernet device name between text and digit groups as int,
allowing consistent sorting of interfaces.
Usage: `sorted(if_list, key=ethkey)`
:param eth: Value to sort
:type eth: str
:return: List of str's (even indexes) and int's (odd indexes) to compare
:rtype: list
"""
keys = []
if not eth:
# If eth is a string it's empty, just return blank list
return keys
# Start with the first character already in last
last, eth = eth[0], eth[1:]
# If last is int we start at offset 1
if last.isdigit():
keys.append('')
for i in eth:
if i.isdigit() is last.isdigit():
# Keep accumulating same type chars
last += i
else:
# Save and restart next round
keys.append(int(last) if last.isdigit() else last)
last = i
# Save final round and return
keys.append(int(last) if last.isdigit() else last)
return keys
It can then be used as such:
sorted(int_list, key=ethkey)
Upvotes: 0
Reputation: 10156
It is sorting by alphabetical order, so you need to break up the numbers and convert them to ints and sort with that. (Numbers in strings are treated as just characters, so it "sees" "A10" and tries to sort it first by "A", then by "1", and then by "0.") For example:
>>> sorted(dir, key=lambda x: int(x[1:]))
['A1', 'A2', 'A3', 'A10']
If you are going to have other letters besides "A" in dir
, you'll need a more complicated sorting method, but it will be something along the same lines. (If you explain what dir
contains more, I can write an example for that.) As mgilson's comment points out, if the elements of dir
follow the 1 char + number format, then you could take advantage of tuple sorting and do something like this:
>>> dir.append('B12')
>>> sorted(dir, key=lambda x: (x[0],int(x[1:])))
['A1', 'A2', 'A3', 'A10', 'B12']
Upvotes: 6