1

I have a list of files that looks something like this:

listOfFiles = ['XLOG100.LOG', 'XLOG101.LOG', 'XLOG102.LOG', 'XLOG103.LOG', 'XLOG104.LOG', 'XLOG105.LOG', 'XLOG106.LOG', 'XLOG107.LOG', 'XLOG108.LOG', 'XLOG109.LOG', 'XLOG110.LOG',   'XLOG92.LOG', 'XLOG93.LOG', 'XLOG94.LOG', 'XLOG95.LOG', 'XLOG96.LOG', 'XLOG97.LOG', 'XLOG98.LOG', 'XLOG99.LOG']

it needs to be sorted from the largest value to the smallest. I came up with the idea to find the largest value following XLOG and create a new list using this algorithm. But is there a simpler way to sort this list? Maybe I missed something. The general pattern for files is: XLOGindex.LOG, where index n > 1.

The final result should look like this:

listOfFiles = ['XLOG110.LOG', 'XLOG109.LOG', 'XLOG108.LOG', 'XLOG107.LOG', 'XLOG106.LOG', 'XLOG105.LOG', 'XLOG104.LOG', 'XLOG103.LOG', 'XLOG102.LOG', 'XLOG101.LOG', 'XLOG100.LOG', 'XLOG99.LOG', 'XLOG98.LOG', 'XLOG97.LOG', 'XLOG96.LOG', 'XLOG95.LOG', 'XLOG94.LOG', 'XLOG93.LOG', 'XLOG92.LOG']

Thanks for any ideas ;)

MrmDdda
  • 41
  • 1
  • 4

3 Answers3

2

You can use function sorted in combination with a "key" function. The key function in your case extracts the numeric part of the file name (from the 4th position to the negative fourth position) and converts it into a number:

sorted(listOfFiles, key=lambda x: int(x[4:-4]), reverse=True)
# ['XLOG110.LOG', 'XLOG109.LOG', 'XLOG108.LOG', 'XLOG107.LOG', 
#  'XLOG106.LOG', 'XLOG105.LOG', 'XLOG104.LOG', 'XLOG103.LOG', 
#  'XLOG102.LOG', 'XLOG101.LOG', 'XLOG100.LOG', 'XLOG99.LOG', 
#  'XLOG98.LOG', 'XLOG97.LOG', 'XLOG96.LOG', 'XLOG95.LOG', 'XLOG94.LOG', 
#  'XLOG93.LOG', 'XLOG92.LOG']
DYZ
  • 55,249
  • 10
  • 64
  • 93
2

Since you only care about the number, you can use filter to filter out everything that isn't a digit; then convert the result to int.

listOfFiles = ['XLOG100.LOG', 'XLOG101.LOG', 'XLOG102.LOG', 'XLOG103.LOG', 'XLOG104.LOG', 'XLOG105.LOG', 'XLOG106.LOG', 'XLOG107.LOG', 'XLOG108.LOG', 'XLOG109.LOG', 'XLOG110.LOG',   'XLOG92.LOG', 'XLOG93.LOG', 'XLOG94.LOG', 'XLOG95.LOG', 'XLOG96.LOG', 'XLOG97.LOG', 'XLOG98.LOG', 'XLOG99.LOG']

listOfFiles.sort(key=lambda s: int(''.join(filter(str.isdigit, s))), reverse=True)

print(listOfFiles)
# ['XLOG110.LOG', 'XLOG109.LOG', 'XLOG108.LOG', 'XLOG107.LOG', 'XLOG106.LOG', 'XLOG105.LOG', 'XLOG104.LOG', 'XLOG103.LOG', 'XLOG102.LOG', 'XLOG101.LOG', 'XLOG100.LOG', 'XLOG99.LOG', 'XLOG98.LOG', 'XLOG97.LOG', 'XLOG96.LOG', 'XLOG95.LOG', 'XLOG94.LOG', 'XLOG93.LOG', 'XLOG92.LOG']
Stef
  • 13,242
  • 2
  • 17
  • 28
0

You can use the python lists sort function to sort your list in place. Use the argument reverse=Trueand key=extract_index with extract_index a function that extract the index your are looking for in your string

l = [
    "XLOG100.LOG",
    "XLOG101.LOG",
    "XLOG102.LOG",
    "XLOG103.LOG",
    "XLOG104.LOG",
    "XLOG105.LOG",
    "XLOG106.LOG",
    "XLOG107.LOG",
    "XLOG108.LOG",
    "XLOG109.LOG",
    "XLOG110.LOG",
    "XLOG92.LOG",
    "XLOG93.LOG",
    "XLOG94.LOG",
    "XLOG95.LOG",
    "XLOG96.LOG",
    "XLOG97.LOG",
    "XLOG98.LOG",
    "XLOG99.LOG",
]
import re


def extract_index(s: str) -> int:
    r = re.search(r"XLOG(\d+).LOG", s)
    if r:
        return int(r.group(1))
    raise ValueError(f"Wrong pattern {s}")

l.sort(reverse=True, key=extract_index)
print(l)
>>> ['XLOG110.LOG', 'XLOG109.LOG', 'XLOG108.LOG', 'XLOG107.LOG', 'XLOG106.LOG', 'XLOG105.LOG', 'XLOG104.LOG', 'XLOG103.LOG', 'XLOG102.LOG', 'XLOG101.LOG', 'XLOG100.LOG', 'XLOG99.LOG', 'XLOG98.LOG', 'XLOG97.LOG', 'XLOG96.LOG', 'XLOG95.LOG', 'XLOG94.LOG', 'XLOG93.LOG', 'XLOG92.LOG']
Axel
  • 126
  • 1
  • 6