2012-02-21 77 views
4

您好我正在Python中使用sorted()函數來訂購一個bi-dimensionnal數組(我想按照它可以在經典電子表格中完成的那樣對列進行排序)。在Python中排序和空字符串

在下面的示例中,我使用itemgetter(0)根據第一列的內容對網格進行排序。

但排序後返回非空的字符串之前的空字符串。

>>> 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())) 

的關鍵是隨後在第一位置,其中true表明,在記錄中的第一項是空白與0(假)的元組或1(真)。第二個位置包含您原始記錄中的名稱字段。然後,Python將首先排序爲非空白和空白名稱組,然後按非空白名稱gorup中的名稱排序。 (Python也會根據空名稱組中的名稱進行排序,但由於名稱的空白,它不會執行任何操作)。

我還冒昧地將名稱整理爲不區分大小寫,情況在關鍵。

只是用「ZZZZZZ」或者「按字母順序排列的高位」來替換空白名稱是誘人的,但是第一次失敗時,一些小丑將自己的名字命名爲「ZZZZZZZZ」進行測試。我猜想像'\xff' * 100可以工作,但它仍然感覺像一個黑客(也可能是Unicode的陷阱)。

+2

我正準備寫這個答案,這是最優雅的方式。元組來「推廣」你的關鍵字母表,而不用修改任何你不想要的東西。 – ninjagecko 2012-02-21 23:06:19

+0

作品非常好,非常感謝! – florian 2012-02-22 09:27:10

-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 2012-02-21 23:04:52

+1

@ninjagecko:我不知道!謝謝你讓我知道 – orlp 2012-02-21 23:07:23

1

你可以通過一鍵功能,返回的實際值,或100「Z的,如果第一個元素是空的(空字符串賦值爲False

sorted(res, key= lambda x: x[0] if x[0] else 'z'*100)