2010-11-30 18 views
1

私は数字のリストを持っていて、特定の順番で(mencoderを使ってムービーを作成するために)名前がリストされたテキストファイル(Pythonを使用)を作成します。特にここでは、数字に月(4月、8月...)が含まれています。私はJanurayのためのものを最初に、そして次に2月にしたい。名前に応じて文字列のリストを注文する

私は醜い方法でそれを行うことができますが、私は両方のエレガント(= pythonic?)と最終的により一般的な解決策に興味があることを知っています。

私のファイルが自然な順序で、以下のとおりです。
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_January_EISopt_1000.png
cld_for_February_EISopt_1000.png
cld_for_March_EISopt_1000.png
cld_for_April_EISopt_1000: cld_for_November_EISopt_1000.pngは
cld_for_October_EISopt_1000.png
cld_for_September_EISopt_1000.png

そして私は、この内部のテキストファイルを持っていると思います。 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一般

以上、私は、リストや配列などdictionnayを持っている場合:
{'pattern1':rank_in_output_list_1、...、 'pattern12':rank_in_output_list_12}
ファイル名を注文するにはどのようにすればよいですか?

これまでのところ、os.listdir、os.path.isfile、numpyp.ma.array、.compressed()、.compress();で再生しました。私はそれほど成功していません。

ありがとうございます。
Christophe。

答えて

1

が、シーケンスを注文するためのより柔軟な答え:

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) 

出力:ここ

cld_for_January_EISopt_1000.png 
cld_for_February_EISopt_1000.png 
cld_for_March_EISopt_1000.png 
cld_for_April_EISopt_1000.png 
    ... 
6

ソートのキーとして、_で分割し、3番目の要素をマップします。長い

sorted(filenames, key=lambda x: monthdict[x.split('_')[2]]) 
0

が私の最後のバージョンです。
私はより多くのpythonic願っています。

一般的なスタイルにコメントしてください。

#!/usr/bin/env python 
"""Demonstrate how to animate multiple figures into a climatology movie.""" 

# 
# Imports 
# 
from os import system 
from os.path import exists 
from numpy import ma 
from glob import glob 
from copy import deepcopy 
from logging import warning 

# 
# Parameters 
# 
month_list = ['January', 
       'February', 
       'March', 
       'April', 
       'May', 
       'June', 
       'July', 
       'August', 
       'September', 
       'October', 
       'November', 
       'December'] 
# 
month_dict = {'January': 0, 
       'February': 1, 
       'March': 2, 
       'April': 3, 
       'May': 4, 
       'June': 5, 
       'July': 6, 
       'August': 7, 
       'September': 8, 
       'October': 9, 
       'November': 10, 
       'December': 11} 
# 
param_dict_default = {'fig_folder': 'figures/era40_correlations/', 
         'output_name': 'output_sol_2.mp4', 
         'fig_criteria': '*climatology*isccp*.png', 
         'order': month_list, 
         'input_file': 'list_fig_for_movie.txt', 
         'splitor': '_', 
         'fps': 10} 

# 
# Functions 
# 
def reorder(seq, extractor, order): 
    "Reorder 'seq' using 'extractor' and according to 'order'.""" 
    rank = dict((v,i) for i,v in enumerate(order)) 
    return sorted(seq, key=lambda v: rank.get(extractor(v),-1)) 

def get_ordering_key(filename, splitor, ind): 
    """Get ordering key in 'filename' at 'ind' position for 'splitor'.""" 
    return filename.split(splitor)[ind] 

def prepareMovie(param_dict={}): 
    """Return the command line to create the movie and the output filename. 

    Input 
    ----- 
    param_dict : dictionary with parameters for creating the movie. 
    Keys:    Default values: 
    * fig_criteria = '*climatology*isccp*.png' 
    * input_file  = 'list_fig_for_movie.txt' 
    * splitor   = '_' 
    * fps    = 10 
    * fig_folder  = 'figures/era40_correlations/' 
    * output_name  = 'output_sol_2.mp4' 
    * order   = ['January', 'February', 'March', 'April', 
          'May', 'June', 'July', 'August', 'September', 
          'October', 'November', 'December'] 
    from: 
    for key in param_dict_default.keys(): 
     print ' * ', key, '=', repr(param_dict_default[key]) 

    Output 
    ------ 
    Command line to create the movie and output filename. 
    """ 

    # Update parameters 
    param_new = deepcopy(param_dict_default) 
    param_new.update(param_dict) 
    # List all selected figures 
    file_names = glob(param_new['fig_folder'] + param_new['fig_criteria']) 
    # Find position of ordering key in name 
    for item in param_new['order']: 
     try: 
      ind = file_names[0].split(param_new['splitor']).index(item) 
     except: 
      pass 
    # Sort all selected figures 
    if isinstance(param_new['order'], list): 
     file_names = sorted(file_names, key=lambda x: param_new['order'].\ 
        index(x.split(param_new['splitor'])[ind])) 
    elif isinstance(param_new['order'], dict): 
     file_names = sorted(file_names, key=lambda x: param_new['order']\ 
        [x.split(param_new['splitor'])[ind]]) 
    else: 
     raise ValueError("param_dict['order'] must be list or dictionary.") 
    # Remove input file for mencoder if already exists 
    if exists(param_new['input_file']): 
     warning(" '%s' existed and has been overwritten." 
       %param_new['input_file']) 
     system("rm %s" %param_new['input_file']) 
    # Write input file for mencoder 
    f = open(param_new['input_file'], "w") 
    for item in file_names: 
     f.write(item+'\n') 
    f.close() 
    # Create command for mencoder 
    command = ['mencoder', 
       'mf://@' + param_new['input_file'], 
       '-mf', 
       "type=png:w=800:h=600:fps=%s" %param_new['fps'], 
       '-ovc', 
       'lavc', 
       '-lavcopts', 
       'vcodec=mpeg4', 
       '-oac', 
       'copy', 
       '-o', 
       param_new['output_name']] 
    # Make it one line white-spaced and return it 
    command = ''.join([item + ' ' for item in command]) 
    return command, param_new['output_name'] 

# 
# Main 
# 
if __name__ == "__main__": 
    [command, output_name] = prepareMovie() 
    # Create the movie 
    system(command) 
    # Open it 
    system("mplayer %s" %output_name) 
+0

質問を編集して回答を追加するのではなく、この情報を含める必要があります。 – meagar

関連する問題