2012-02-21 40 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)