I have a list of sublists of arbitrary lengths, populated with strings, both alpha and numeric. I want to sort this list first by the first element of each sub-list, then by the second element, and so on. Numeric strings should be treated as integers or floats, so that for example '100' is placed after '12', not before.
Here’s an example input list:
[['10001', '1002', '501'],
['10001', '1002', '5001'],
['1001', '1002', '5'],
['1', '1002', '5'],
['1', '102', '6'],
['1', '12', '4'],
['10', '11', '3'],
['mihail', '1', '2'],
['1', 'mihail', '1']]
The desired output after sorting is:
[['1', '12', '4'],
['1', '102', '6'],
['1', '1002', '5'],
['1', 'mihail', '1'],
['10', '11', '3'],
['1001', '1002', '5'],
['10001', '1002', '501'],
['10001', '1002', '5001'],
['mihail', '1', '2']]
That’s the approach I have tried:
def true_numeric(string_):
allowed = '0123456789.'
for char in string_:
if char not in allowed:
return False
point_count = sum([1 for char in string_ if char=='.'])
if point_count > 1:
return False
return True
def numeric_strings_sort_key(item):
result = []
for element in item:
if true_numeric(element):
result.append((0, float(element)))
else:
result.append((1, element))
return tuple(result)
my_list = [
['10001', '1002', '501'],
['10001', '1002', '5001'],
['1001', '1002', '5'],
['1', '1002', '5'],
['1', '102', '6'],
['1', '12', '4'],
['10', '11', '3'],
['mihail', '1', '2'],
['1', 'mihail', '1']
]
my_list.sort(key=numeric_strings_sort_key)
print(my_list)
This code uses a custom true_numeric function to determine whether a string represents a valid floating-point number and treats it as such when sorting. The numeric_strings_sort_key function uses this function to construct a sorting key tuple that correctly handles mixed data types.
However, I’m not sure if this is the best approach or if there’s a simpler or more efficient way to achieve the desired result. Is there a better way to sort a list of lists with mixed data types and an arbitrary number of levels in Python?