Reverse a list in python based on condition

  • A+

I want to sort this list in a way that .log should be the first file and .gz file should be in a descending order

my_list = [      '/abc/a.log.1.gz',      '/abc/a.log',      '/abc/a.log.30.gz',      '/abc/a.log.2.gz',      '/abc/a.log.5.gz',      '/abc/a.log.3.gz',      '/abc/a.log.6.gz',      '/abc/a.log.4.gz',      '/abc/a.log.12.gz',      '/abc/a.log.10.gz',      '/abc/a.log.8.gz',      '/abc/a.log.14.gz',      '/abc/a.log.29.gz' ] 


my_list = ['/abc/a.log',         '/abc/a.log.30.gz',         '/abc/a.log.29.gz',         '/abc/a.log.29.gz',         '/abc/a.log.14.gz',         '/abc/a.log.12.gz',         '/abc/a.log.10.gz',         '/abc/a.log.8.gz',         '/abc/a.log.6.gz',         '/abc/a.log.5.gz',         '/abc/a.log.4.gz',         '/abc/a.log.3.gz',         '/abc/a.log.2.gz'         '/abc/a.log.1.gz'] 

reversed(mylist) is also not getting me the desired solution.


Use sorted with a custom key function and reverse=True:

print(sorted(my_list, key=lambda x: (x.endswith('log'), x), reverse=True)) #['/abc/spa/a.log', # '/abc/spa/a.log.30.gz', # '/abc/spa/a.log.2.gz', # '/abc/spa/a.log.1.gz'] 

Based on the updated question, it seems like you are trying to sort file names. I would recommend using os.path to manipulate these strings.

First you can use os.path.splitext split out the extension to compare between .log or .gz. Then strip off the extension again to get the file number, and convert it to an integer.

For example:

import os  def get_sort_keys(filepath):     split_file_path = os.path.splitext(filepath)     sort_key = (split_file_path[1], *os.path.splitext(split_file_path[0]))     return (sort_key[0], sort_key[1], int(sort_key[2].strip(".")) if sort_key[2] else 0)  print(sorted(my_list, key=get_sort_keys, reverse=True)) #['/abc/a.log', # '/abc/a.log.30.gz', # '/abc/a.log.29.gz', # '/abc/a.log.14.gz', # '/abc/a.log.12.gz', # '/abc/a.log.10.gz', # '/abc/a.log.8.gz', # '/abc/a.log.6.gz', # '/abc/a.log.5.gz', # '/abc/a.log.4.gz', # '/abc/a.log.3.gz', # '/abc/a.log.2.gz', # '/abc/a.log.1.gz'] 

In this version, I am not explicitly checking for endswith("log") as before, but I am relying on the fact that the log extension will sort after gz lexicographically.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: