i want to arrange some items of my list in a following order.
raw_list = ['L1', 'L2', 'J1', 'L10', 'L12', 'J10', 'P2', 'P5', 'P11' ]
i want it to order it as L(ascending_integer), J(ascending_interger) and P(ascending_integer).
like as follows,
arranged_list = [
'L1', 'L2', 'L10', 'L12',
'J1', 'J10',
'P1', 'P5', 'P11'
]
how can i do it?
CodePudding user response:
You can pass a key
function to list.sort
or sorted
:
raw_list = ['L1', 'L2', 'J1', 'L10', 'L12', 'J10', 'P2', 'P5', 'P11']
arranged_list = sorted(raw_list, key=lambda x: ('LJP'.index(x[0]), int(x[1:])))
# ['L1', 'L2', 'L10', 'L12', 'J1', 'J10', 'P2', 'P5', 'P11']
This will raise a ValueError
if a string starts with a letter other than L, J, or P.
raw_list = ['L1', 'L2', 'J1', 'L10', 'L12', 'J10', 'P2', 'P5', 'X11']
arranged_list = sorted(raw_list, key=lambda x: ('LJP'.index(x[0]), int(x[1:])))
# ValueError: substring not found
If you want to instead place such strings at the start, use 'LJP'.find(x[0])
.
arranged_list = sorted(raw_list, key=lambda x: ('LJP'.find(x[0]), int(x[1:])))
# ['X11', 'L1', 'L2', 'L10', 'L12', 'J1', 'J10', 'P2', 'P5']
If you want to place them at the end, use -'PJL'.find(x[0])
.
arranged_list = sorted(raw_list, key=lambda x: (-'PJL'.find(x[0]), int(x[1:])))
# ['L1', 'L2', 'L10', 'L12', 'J1', 'J10', 'P2', 'P5', 'X11']
CodePudding user response:
You can define a custom key function for sort as follows:
raw_list = ['L1', 'L2', 'J1', 'L10', 'L12', 'J10', 'P2', 'P5', 'P11']
def sort_key(s):
alphabet_order={k: i for i, k in enumerate('LJP')}
return (alphabet_order[s[0]], int(s[1:]))
output = sorted(raw_list, key=sort_key)
print(output)
# ['L1', 'L2', 'L10', 'L12', 'J1', 'J10', 'P2', 'P5', 'P11']
Or, using closure (twice faster):
def sort_key(alphabets):
alphabet_order = {k: i for i, k in enumerate(alphabets)}
return lambda s: (alphabet_order[s[0]], int(s[1:]))
output = sorted(raw_list, key=sort_key('LJP'))