2011-03-30 147 views
8

如果我有一个字符串列表例如["a143.txt", "a9.txt", ]我如何按照列表中的数字升序排序,而不是字符串。即自9 < 143起,我希望"a9.txt"出现在"a143.txt"之前。Python中的排序列表

谢谢。

+2

是前缀始终'了'? – poke 2011-03-30 20:26:07

+1

这个问题似乎与'scipy'或'numpy'没有任何关系。如果是这种情况,请删除这些标签。 – JoshAdel 2011-03-30 20:35:35

+1

已编辑标签。现在更清楚了。 – 2011-03-30 20:45:23

回答

13

这就是所谓的 “自然排序”, 从http://www.codinghorror.com/blog/2007/12/sorting-for-humans-natural-sort-order.html

试试这个:

import re 

def sort_nicely(l): 
    """ Sort the given list in the way that humans expect. 
    """ 
    convert = lambda text: int(text) if text.isdigit() else text 
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] 
    l.sort(key=alphanum_key) 
+0

我会在'convert ='行的末尾使用'text.lower()'来使其不区分大小写。 – kindall 2011-03-30 20:36:59

+0

+1。为了便于阅读,您可能需要使用适当的函数定义替换lambda表达式。顺便提一下,Debian软件包的版本号或多或少是这样比较的。 http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version – 2011-03-30 20:44:54

+1

+1好的答案。我唯一不喜欢的是额外的空白。我的意思是:'[在re.split('([0-9] +)',key)]'和'l.sort(key = alphanum_key)'和'sort_nicely(l) – 2011-03-30 20:56:46

0

如果你想完全不顾字符串,那么你应该做

import re 
numre = re.compile('[0-9]+') 
def extractNum(s): 
    return int(numre.search(s).group()) 

myList = ["a143.txt", "a9.txt", ] 
myList.sort(key=extractNum) 
+0

为什么downvote? – highBandWidth 2011-03-30 20:55:39

0

list.sort()已被弃用(见Python.org How-To)。 sorted(list, key=keyfunc)比较好。

import re 

def sortFunc(item): 
    return int(re.search(r'[a-zA-Z](\d+)', item).group(1)) 

myList = ["a143.txt", "a9.txt"] 

print sorted(myList, key=sortFunc) 
+0

list.sort()已被弃用? “通常它不如排序()方便”是我发现的这个方向唯一的东西。不过,我必须说,我很乐意看到就地分拣消失,但似乎不大可能。 – tokland 2011-03-30 20:59:53

+1

它不被弃用。 http://docs.python.org/library/stdtypes.html#mutable-sequence-types – 2011-03-30 21:03:24

+0

它可能不会在技术上折旧,但它被认为是“旧”的方法,并在Python.org上标记。 – Prydie 2011-03-30 21:10:04

0
>>> paths = ["a143.txt", "a9.txt"] 
>>> sorted(paths, key=lambda s: int(re.search("\d+", s).group())) 
['a9.txt', 'a143.txt'] 

更通用的,如果你希望它也努力像文件:a100_32_12(和数值编组排序):

>>> paths = ["a143_2.txt", "a143_1.txt"] 
>>> sorted(paths, key=lambda s: map(int, re.findall("\d+", s))) 
['a143_1.txt', 'a143_1.txt']