2017-06-28 6 views
1

ちょうどのpythonで作業を開始し、試合の倍数/変数で文字列リストをソートする難しさを持つ一致します。基本的には、文字列のリストがあれば、各文字列を与えられた正規表現(ユーザ提供)で分割し、与えられたキーのリスト(場所)でソートする必要があります。キーは、単一の整数でもソート順のリストでもかまいません。たとえば、Pythonのソート・リストは

regex = r 'です。 (FF | TT | SS)_([ - 。\ d] + v)_([ - 。\ d] + c)_(FF | TT | SS)

キー= [2,1,3]

はLOCATION2、LOCATION1、LOCATION3によって文字列のリストを並べ替えるだろう。

私は場所/キーの固定数のために働く、以下を持っているが、それは「キー」の数を変えることで動作するように取得する方法を見つけ出すことはできません。

import re 

strlist = ["synopsys_SS_2v_-40c_SS.lib","synopsys_SS_1v_-40c_SS.lib","synopsys_SS_2v_-40c_TT.lib","synopsys_FF_3v_-40c_FF.lib", "synopsys_TT_4v_125c_TT.lib", "synopsys_TT_1v_-40c_TT.lib"] 
regex = r'.*(FF|TT|SS)_([-\.\d]+v)_([-\.\d]+c)_(FF|TT|SS).*' 
key = [2,1,3] 

sfids_single = sorted(strlist, key=lambda name: ( 
    re.findall(regex,name)[0][key[0]], 
    re.findall(regex,name)[0][key[1]], 
    re.findall(regex,name)[0][key[2]])) 

は、次のことを試みたが、動作していないよう:

fids_single = sorted(strlist, key=lambda name: (re.findall(regex,name)[0][i] for i in key)) 

はまた、(W/O成功)を試してみました:

for i in key: 
    strlist.sort(key=lambda name: re.findall(regex,name)[0][key[i]]) 

予想R esult:

['synopsys_SS_1v_-40c_SS.lib', 'synopsys_TT_1v_-40c_TT.lib', 'synopsys_SS_2v_-40c_SS.lib', 'synopsys_SS_2v_-40c_TT.lib', 'synopsys_FF_3v_-40c_FF.lib', 'synopsys_TT_4v_125c_TT.lib'] 

私は間違ったトラックにいますか?どんな指針も大変ありがとうございます。

+0

文字列の分割や結果リストのソートに問題がありますか? – wwii

+0

希望の出力のサンプルを表示できますか? –

+0

これは宿題に関する質問ですか? – wwii

答えて

1

感謝します。

fids_single = sorted(strlist, key=lambda name: tuple(re.findall(regex,name)[0][i] for i in key)) 
2

は、優先度の高い順に、各列のrelevent部分を返し、ソート・キーのためにその機能を使用するキーの機能を記述します。

one = ["synopsys_SS_2v_-40c_SS.lib","synopsys_SS_1v_-40c_SS.lib", 
     "synopsys_SS_2v_-40c_TT.lib","synopsys_FF_3v_-40c_FF.lib", 
     "synopsys_TT_4v_125c_TT.lib", "synopsys_TT_1v_-40c_TT.lib"]  

expected = ['synopsys_SS_1v_-40c_SS.lib', 'synopsys_TT_1v_-40c_TT.lib', 
      'synopsys_SS_2v_-40c_SS.lib', 'synopsys_SS_2v_-40c_TT.lib', 
      'synopsys_FF_3v_-40c_FF.lib', 'synopsys_TT_4v_125c_TT.lib'] 

正規表現を使用して文字列を分割します。

import operator, re 
pattern = r'.*(FF|TT|SS)_([-\.\d]+v)_([-\.\d]+c)_(FF|TT|SS).*' 
rx = re.compile(pattern) 
seq = [2,1,3] 
def key(item, seq = seq): 
    seq = operator.itemgetter(*seq) 
    a, b, c, d = rx.findall(item) 
    return seq([a, b, c, d]) 


one.sort(key = key) 
assert one == expected 

キーの機能は、それが少し少ない複雑にして正規表現を使用せずに書き込むことができます。

def key(item, seq = seq): 
    seq = operator.itemgetter(*seq) 
    _, a, b, c, d = item.split('_') 
    d, _ = d.split('.') 
    print a, b, c, d 
    return seq([a, b, c, d]) 

a, b, c, dよりわかりやすい名前を使用できます。これは同じパターンを持つ文字列に依存しています。パズルの欠けている部分を提供するための@a_guestする

+0

これを自分のコードにどのように適用できるかわかりません。 – Luca

+1

@Kidneys 'for i in key'での最初の試みはほぼ正しいですが、あなたが使った表現はジェネレータを返します。ソートキーの代わりに 'tuple'を使いたいとします。ですから、 'lambda name:tuple(キーのiのために...)'を使うことでうまくいくはずです。 –

+0

@キドニー - 解決された解決策。 – wwii

関連する問題