2012-02-21 15 views
4

こんにちは私は二次元の配列を注文するためにPythonでsorted()関数を使用しています(私は古典的なスプレッドシートで行うことができるように列を並べ替えたいです)。Pythonで並べ替えると空の文字列

以下の例では、最初の列の内容に基づいてグリッドをソートするためにitemgetter(0)を使用します。

ただし、sortedは、空でない文字列の前に空の文字列を返します。

>>> import operator 
    >>> res = [['charly','male','london'], 
    ... ['bob','male','paris'], 
    ... ['alice','female','rome'], 
    ... ['','unknown','somewhere']] 
    >>> sorted(res,key=operator.itemgetter(0)) 
    [['', 'unknown', 'somewhere'], ['alice', 'female', 'rome'], ['bob', 'male', 'paris'], ['charly', 'male', 'london']] 
    >>> 

私はこれを返すためにそれを必要とするだろうが:

[['alice', 'female', 'rome'], ['bob', 'male', 'paris'], ['charly', 'male', 'london'], ['', 'unknown', 'somewhere']] 

はそれを行う簡単な方法はありますか?

答えて

18

異なるキー機能を使用してください。うまくいくものである:

sorted(res, key=lambda x: (x[0] == "", x[0].lower())) 

キーは、レコードの最初の項目が空白であることを示して真第1の位置で、0(偽)とのタプルまたは1(TRUE)です。 2番目の位置には元のレコードの名前フィールドがあります。 Pythonは最初に空でない名前と空白の名前のグループにソートし、非ブランクの名前gorup内で名前をソートします。 (空白の名前グループ内では名前によってソートされますが、名前の空白は何もしません)

また、大文字と小文字を区別しない名前を小文字に変換することで、キーのケース。

空白の名前を "ZZZZZZ"または何か "アルファベット順に高い"に置き換えるのは魅力的ですが、ジョーカーがテストのために "ZZZZZZZZ"という名前を付けたのは初めてです。私は'\xff' * 100のようなものがあると思うが、それはまだハックのように感じる(また、潜在的なUnicodeの落とし穴)。

+2

私はこの答えを正確に書こうとしていた;これはこれを行う最もエレガントな方法です。あなたがしたくないものを変更することなく、あなたのキーアルファベットを「プロモート」するタプル – ninjagecko

+0

大変お世辞になります。 – florian

-2
key=lambda x: x[0] if x[0] else '\xff\xff\xff\xff\xff\xff\xff\xff\xff' 
0

これは動作しますが、それは少し冗長に:

def cmp_str_emptylast(s1, s2): 
    if not s1 or not s2: 
     return bool(s2) - bool(s1) 

    return cmp(s1, s2) 

sorted(res, key=operator.itemgetter(0), cmp=cmp_str_emptylast) 
+1

これだけpython2.Xで動作します; 'CMPを===は愚かな 'key =' – ninjagecko

+1

のために愚かに非難されています@ninjagecko:私は分かりませんでした!私に知らせてくれてありがとう – orlp

1

あなたが最初の要素が(空の文字列がFalseに評価され、空の場合は実際の値、または100」のzを返す、キーの機能を渡すことができ

sorted(res, key= lambda x: x[0] if x[0] else 'z'*100) 
関連する問題