Sort String like a number if it leads with a number

536
1
09-18-2015 06:45 AM
Status: Open
RobertBorchert
Frequent Contributor III
I would like to see the ability to sort a string that has numbers at the beginning as a Number.

i.e.  I have addresses 1 Main Street,  10 Main Street, 2 Main Street.  It is going to sort them in that order.
1 Comment
DanPatterson_Retired

Until such time that this happens... You can do it with a field calculator expression in the interim if you are in a pinch

Create them correctly in the first place

def nat_pad(val, pad='0000'):
    """natural sort... put the import re outside of the function
    :if using the field calculator
    : calculator expression- nat_pad(!data_field!, pad='a bunch of 0s')
    """
    import re
    txt = re.split('([0-9]+)', val)
    l_val = len(str(val))
    txt_out = "{}{}{}".format(txt[0], pad[:-l_val], txt[1])
    return txt_out

a = ['a1', 'a20', 'a2', 'a10']
print("input - \n{}".format(a))
vals = [nat_pad(i) for i in a]
print("output - \n{}".format(vals))


input - 
['a1', 'a20', 'a2', 'a10']
output - 
['a001', 'a020', 'a002', 'a010']‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Then sort

b = ['a001', 'a020', 'a002', 'a010']

b.sort()

b
['a001', 'a002', 'a010', 'a020']

Sort them if they aren't

def natsort(text_lst):
    """natural sort returns text containing numbers sorted considering the
    :  number in the sequence.
    :originals used lambda expressions
    :  convert = lambda text: int(text) if text.isdigit() else text
    :  a_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
    """
    import re
    def convert(text):
        return int(text) if text.isdigit() else text

    def a_key(key):
        return [convert(c) for c in re.split('([0-9]+)', key)]

    return sorted(text_lst, key=a_key)



a = ['a1', 'a20', 'a2', 'a10']
vals = natsort(a)
print("natural sort - \n{}".format(vals))


natural sort - 
['a1', 'a2', 'a10', 'a20']‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍