使用数字对列表进行排序

时间:2015-04-11 01:17:18

标签: python python-2.7 sorting

如果我的列表中包含所有字符串,但带有数字:

a = ['0.01um', 'Control', '0.1um', '0.05um']

如果我对列表进行排序,它看起来像这样

a.sort()
print(a)
['0.01um', '0.05um', '0.1um', 'Control']

如何对其进行排序,以字母开头的字符串出现在以数字开头的字符串之前,但数字仍然从最小到最大排序。例如:

['Control', '0.01um', '0.05um', '0.1um']

4 个答案:

答案 0 :(得分:3)

好吧,为了让你的字符串以字母开头整理,然后用数字开头,你需要将它们分开,然后对每个字符进行排序,然后将一个(子)列表附加到另一个。

要对包含数字的字符串进行“自然”排序,我会看natsort

因此代码可能类似于:

#!python
# UNTESTED
import string
from natsort import natsorted
a = ['0.01um', 'Control', '0.1um', '0.05um']
astrs = [x for x in a if not x[0] in string.digits]
anums = [x for x in a if x[0] in string.digits]
results = natsorted(astrs) + natsorted(anums)

答案 1 :(得分:0)

您可以定义一个“装饰”字符串的键函数,该字符串以低于以数字开头的字符串开头的字母开头。例如:

from itertools import takewhile

def get_numeric_prefix(str_):
    return float(takewhile(char.isnumeric() or char == '.'))

def letters_before_numbers(str_):
    if not str_:
        return (3, str_)
    elif str_[0].isalpha():
        return (0, str_)
    elif str_[0].isnumeric():
        return (1, get_numeric_prefix(str_))
    else:
        return (2, str_)

a.sort(key=letters_before_numbers)

初始not str_情况是必要的,因为后面的情况中的条件访问项0,如果字符串为空,则会引发IndexError。我选择不处理'40.0.3um'之类的字符串(其中包含所有数字和点的前缀,但它的格式不正确float )-those将导致float()调用引发ValueError。如果您需要处理这些内容,则应该grab a copy of natsortuse Jim's answer

元组按字典顺序进行比较,因此sort()首先查看数字 - 如果它更低,原始字符串将在列表的前面排序。这意味着您可以使用作为返回值的第一个元素的数字来获取不同类型的字符串,以便比其他字符串更早或更晚排序。在这种情况下,以字母开头的字符串将首先排序,然后是以数字开头的字符串(按数字排序),然后是以两个字母开头的字符串,最后是空字符串。

答案 2 :(得分:0)

这是一个涉及python的元组排序语义的技巧;不以数字开头的字符串将在所有将按数字排序的数字之前以词汇方式排序:

In [1]: import re

In [2]: def parse_number(s):
    try:
        m = re.match(r'\d+(?:\.\d+)?', s)
        return m and float(m.group(0))
    except:
        pass

In [3]: a = ['0.01um', 'Control', '0.1um', '0.05um']

In [4]: b = sorted((parse_number(i), i) for i in a)

In [5]: [i for _, i in b]
Out[5]: ['Control', '0.01um', '0.05um', '0.1um']

答案 3 :(得分:-1)

代码

a = ['0.01um', 'Control', '0.1um', '0.05um']
b = [x for x in a if x and x[0].isdigit()]
c = [x for x in a if x not in b]
d = sorted([(x, float(''.join([y for y in x if y.isdigit() or y == '.']))) for x in b], key=lambda x: x[1])
print sorted(c) + [k for k, v in d]