您好我在Python中使用sorted()函数来订购一个二维数组(我想对列进行排序就像在经典电子表格中完成一样)。
在下面的示例中,我使用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']]
有一种简单的方法吗?
答案 0 :(得分:19)
使用其他键功能。一个可行的方法是:
sorted(res, key=lambda x: (x[0] == "", x[0].lower()))
键是第一个位置的0(False)或1(True)元组,其中True表示记录中的第一个项目为空。第二个位置具有原始记录中的名称字段。然后,Python将首先排序为非空白和空白名称组,然后在非空名称gorup中按名称排序。 (Python也将在空白名称组中按名称排序,但由于名称为空白,因此不会执行任何操作。)
我还冒昧地通过在密钥中将它们全部转换为小写来使名称排序不区分大小写。
用“ZZZZZZ”或“字母高”替换空白名称很诱人,但是第一次有些小丑将他们的名字命名为“ZZZZZZZZ”进行测试时失败了。我想像'\xff' * 100
这样的东西可以工作,但它仍然感觉像是一个黑客(也是潜在的Unicode陷阱)。
答案 1 :(得分:1)
如果第一个元素为空,您可以传递一个键函数,返回实际值,或者100'如果第一个元素为空(空字符串计算为False
。
sorted(res, key= lambda x: x[0] if x[0] else 'z'*100 )
答案 2 :(得分: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)
答案 3 :(得分:-2)
key=lambda x: x[0] if x[0] else '\xff\xff\xff\xff\xff\xff\xff\xff\xff'