Christophe Christophe - 3 months ago 10
Python Question

ordering a list of string according to name (month)

I have a list of figures and I want to create a text file (using python) with their names listed in a specific order (for a movie creation with mencoder). In particular here, the figure names include months (April, August...). I want the one for Januray first, then February and so on.

I know I could do it in an ugly way, but I am interested in a solution which would be both elegant (=pythonic?) and eventually more general.

My files are, in natural order:

cld_for_April_EISopt_1000.png

cld_for_August_EISopt_1000.png

cld_for_December_EISopt_1000.png

cld_for_February_EISopt_1000.png

cld_for_January_EISopt_1000.png

cld_for_July_EISopt_1000.png

cld_for_June_EISopt_1000.png

cld_for_March_EISopt_1000.png

cld_for_May_EISopt_1000.png

cld_for_November_EISopt_1000.png

cld_for_October_EISopt_1000.png

cld_for_September_EISopt_1000.png

And I want to have a text file with this inside:

cld_for_January_EISopt_1000.png

cld_for_February_EISopt_1000.png

cld_for_March_EISopt_1000.png

cld_for_April_EISopt_1000.png

cld_for_May_EISopt_1000.png

cld_for_June_EISopt_1000.png

cld_for_July_EISopt_1000.png

cld_for_August_EISopt_1000.png

cld_for_September_EISopt_1000.png

cld_for_October_EISopt_1000.png

cld_for_November_EISopt_1000.png

cld_for_December_EISopt_1000.png

Or more generally, if I have a list or an array or a dictionnay like:

{'pattern1': rank_in_output_list_1, ..., 'pattern12': rank_in_output_list_12}

how should I do to use it to order my file names?

So far I have played with: os.listdir, os.path.isfile, numpyp.ma.array, .compressed() or .compress() ; but I haven't been so successful.

Thanks a lot.

Christophe.

Answer

Longer, but more flexible answer for ordering sequences:

import collections

def rearrange(seq, order, keyfunc):
    if not isinstance(order, collections.Mapping):
        order = {v: i for i,v in enumerate(order)}
    return sorted(seq, key=lambda x: order[keyfunc(x)])

if __name__ == '__main__':
    filenames = """
        cld_for_April_EISopt_1000.png    cld_for_August_EISopt_1000.png
        cld_for_December_EISopt_1000.png cld_for_February_EISopt_1000.png
        cld_for_January_EISopt_1000.png  cld_for_July_EISopt_1000.png
        cld_for_June_EISopt_1000.png     cld_for_March_EISopt_1000.png
        cld_for_May_EISopt_1000.png      cld_for_November_EISopt_1000.png
        cld_for_October_EISopt_1000.png  cld_for_September_EISopt_1000.png
    """.split()

    months = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
              'August', 'September', 'October', 'November', 'December']

    def get_month_name(filename):
        return filename.split('_')[2]

    for filename in rearrange(filenames, months, get_month_name):
        print(filename)

Output:

cld_for_January_EISopt_1000.png
cld_for_February_EISopt_1000.png
cld_for_March_EISopt_1000.png
cld_for_April_EISopt_1000.png
  ...
Comments