How to sort a list of strings following a certain pattern
design-patterns, list, python, sorting
Solution
My two cents... This has a 'patternList' variable that defines the order. This is probably the easiest (most human readable, expandable) way to implement this: no messy if-elses. Also, the list items with the same starting pattern is ordered by the rest of the string.
The `list1.sort(key = myKey)` means that for each list item `myKey` function is executed before sorting. `myKey` function modifies the sorted list items for sorting purposes only in a way that normal sort will do what you want. In the output sorted list the original list item is not used (not the one `myKey` modified).
In the example below, the myKey function splits the list items in to two parts and labels the first with integer according to patternList variable. Normal sort can handle the returned tuple in a way you want.
list1 = ['3DT1_PN_DIS3D_S001', '3DT1_PN_noDIS3D_S001', '3DT1_S001', '3DT1_noPN_DIS3D_S001']
list2 = ['3DT1_noPN_DIS3D_S002', '3DT1_PN_noDIS3D_S002', '3DT1_PN_DIS3D_S002', '3DT1_PN_DIS3D_S003', '3DT1_PN_DIS3D_S001']
def myKey(x):
# create the 'order list' for starting pattern
patternsList = [ '3DT1_S', '3DT1_noPN_DIS3D_S', '3DT1_PN_noDIS3D_S', '3DT1_PN_DIS3D_S']
for i in range(len(patternsList)): # iterate patterns in order
pattern = patternsList[i]
if x.find(pattern) == 0: # check if x starts with pattern
# return order value i and x without the pattern
return (i, x.replace(pattern, ''))
# if undefined pattern is found, put it to first
return (-1, x)
# alternatively if you want undefind to be last
# return (len(patternList)+1, x)
print list1
list1.sort(key = myKey)
print list1
print list2
list2.sort(key = myKey)
print list2
Problem
I want to sort every lists of strings, such as : ``` list1 = ['3DT1_PN_DIS3D_S001', '3DT1_PN_noDIS3D_S001', '3DT1_S001', '3DT1_noPN_DIS3D_S001'] list2 = ['3DT1_noPN_DIS3D_S002', '3DT1_PN_noDIS3D_S002', '3DT1_PN_DIS3D_S002'] ``` following the pattern `[ '3DT1_S##', '3DT1_noPN_DIS3D_S##', '3DT1_PN_noDIS3D_S##', '3DT1_PN_DIS3D_S##']` the outcome should be : ``` list1 = [ '3DT1_S001', '3DT1_noPN_DIS3D_S001', '3DT1_PN_noDIS3D_S001', '3DT1_PN_DIS3D_S001'] list2 = [ '3DT1_noPN_DIS3D_S002', '3DT1_PN_noDIS3D_S002', '3DT1_PN_DIS3D_S002'] ``` I tried to play a bit with the sorted method, but with no luck ! Any help ?