2011-11-03 10 views
6

私はこのようになります一連のリストがあります:Pythonでカスタム並べ替えパラメータを使用してリストを並べ替える最も良い方法は何ですか?

li1 = ['a.1', 'b.9', 'c.8', 'd.1', 'e.2'] 
li2 = ['a.4', 'b.1', 'c.2', 'd.2', 'e.4'] 

最初の項目は「b.something」となるように、私は、各リスト内の項目を並べ替えることができますどのように?上記の例の場合:

li1 = ['b.9', 'a.1', 'c.8', 'd.1', 'e.2'] 
li2 = ['b.1', 'a.4', 'c.2', 'd.2', 'e.4'] 

最初の項目の後に注文を維持することは重要ではありません。助けてくれてありがとう。

+0

私はよく分かりませんが、この質問はあなたにとって興味深いかもしれません:http://stackoverflow.com/questions/2436607/how-to-use-re-match-objects-in-a-list-comprehension –

+0

なぜ誰もが 's [0] == 'b''の代わりに' s.startwith(' b ') 'を使っていたのか疑問に思っています。パフォーマンス上の利点はありますか?そうでなければ、私は自分の脳の長期記憶を保存したいと思っています。 – yosukesabai

+0

@yosukesabai:答えは 's.startwith( 'b')'だけです。他の人は、質問で尋ねられたような 's.startwith( 'b。')'を使います。 –

答えて

4

最初の項目は、最初の項目は重要ではありません後

は秩序を維持「b.something」されるように、各リストの項目を並べ替えます。

これはソートされていません。概念的には、その要素を前面に持ってきているだけです。

つまり、その要素で構成され、その要素以外のすべての要素で構成されるリストが必要です。最初の要素がb.somethingである限り何も起こらないことに注意して、b.somethingが複数ある場合はこれをちょっと読んで、次のように言い換えることができます:条件を満たすすべての要素のリスト( "starts b. ")、条件に合致しないすべての要素が続きます。 (これは、時には分割と呼ばれ、C++の例std::partition参照)

Pythonでは、これはリストの内包とそれら2つのリスト・コンポーネントを記述し、それらを一緒に貼り付けるように単純である:

[x for x in li if x.startswith('b.')] + [x for x in li if not x.startswith('b.')] 

...またはあなたがソートしているとふりかけることができます。ちょうどkeyが適用された後実際には2つの値を持つ要素がたくさんあり、Ignacio Vasquez-Abramsの答えのように適切なkeyを適用します。

+0

リクエストに最も近い。とにかく、フィルタリングのために同じ関数でリストを2回読まなければならないので、私はどのくらい速くそれが 'sort'に関係するか分かりません。 –

+0

うわー、これはクールです。何らかの理由でリスト内包表記を一緒に結合することは決して私には起こりませんでした。ありがとう。 – drbunsen

+0

@Joëlはリストを2度読むだけで、定数因子のオーバヘッドを引き起こします。 'sort'は任意にソートできる必要があり、ある種の比較ベースソートを行う必要があり、各フィルタリングリスト理解度はO(n)であると見なされるため、ソートはO(n lg n)です。 –

3

あなたはsortedを使用することができ、key引数を受け取り、リストを返します:

>>> li1 = ['a.1', 'b.2', 'c.8'] 
>>> def k(s): 
...  if s.startswith('b.'): 
...   return 1 
...  else: 
...   return 2 
... 
>>> sorted(li1, key=k) 
['b.2', 'a.1', 'c.8'] 

k反復可能な項目の間で比較することができるものを返還しなければなりません。

注:sortsortedがソートされたリストを返してもリストを変更しない場合は、インプレースの入力を変更して何も返しません。どちらも同じように動作します。

5

Pythonの並べ替えは安定しているので、最初の項目の後に順序を維持します。

li1.sort(key=lambda x: not x.startswith('b.')) 
+1

これは非常に滑らかですが、「明示的なほうが暗黙的である」とは、ブール値を比較可能な値( 'False

関連する問題