Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用数字对列表进行排序_Python_Python 2.7_Sorting - Fatal编程技术网

Python 用数字对列表进行排序

Python 用数字对列表进行排序,python,python-2.7,sorting,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'] 好的,

如果我有一个列表,其中包含除数字以外的所有字符串:

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']

好的,为了让以字母开头的字符串在那些以数字开头的字符串听起来像是需要将它们分开之前进行整理,请对每个字符串进行排序,然后将一个(子)列表附加到另一个列表

要获得包含数字的字符串的“自然”排序,我将查看

因此,代码可能类似于:

#!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)

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

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_uu
案例是必需的,因为后面案例中的条件访问项
0
,如果字符串为空,则会引发
索引器。我选择不处理像
'40.0.3um'
这样的字符串(其中有一个前缀是所有数字和点,但它不是格式正确的
float
)-这将导致
float()
调用引发
ValueError
。如果您需要处理这些问题,您可能应该并且

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

在代码中

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]

下面是一个涉及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']

这就跳过了最难的部分:将数字从最小到最大排序,而不是按字母顺序排列。如果所有的数字都是呜呼。我想我们都错过了那一点。;他明白了。(我得到它的唯一原因是问自己“他为什么想要natsort
?”,然后重新阅读这个问题。:-1(是的,我对自己的答案投了反对票):这几乎没有我想要的那么稳健,而且我不喜欢从字符串中解析数字的方式。也许这样一个关键定义在另一个上下文中是合适的,但不是在这里。首选按字符串开头的数字对字符串进行正确排序。
natsort
是否有选项将任何数字部分视为大于任何数字部分,而不是更小?如果是这样的话,这将把整个事情减少到一行。如果没有,这可能是你能得到的最简单的。我不知道
natsort
的所有特性和皱纹。。。我只记得很久以前,我在一些琐碎的用例中发现了它。。。例如对IP地址的长列表进行排序)。如果你想看看他们是否能为你做到这一点,就把这些资料翻个底朝天。好吧,OP可以翻个底朝天。:)我使用了
natsort
一次,将一些PyObjC代码移植到可移植的纯Python上,它的默认值与Cocoa的默认值非常接近,我所有的单元测试都通过了,所以这就是我所看到的。我只记得它有一大堆看起来很别致的选项,我想它可能有一个选项可以让这变得更简单。浏览文档,它看起来有,你应该结合使用它来生成一个键函数。让它成为一种理解也可以避免生成两个列表然后将它们连接起来的开销。通过稍微使用
natsort
,它看起来会对默认情况下与结尾不匹配的字符串进行排序。您可以将最后三行替换为
results=sorted(a,key=natsort.natsort\u keygen(alg=natsort.ns.FLOAT))
。您的数字有多复杂?它们可能是指数表示法吗?您的字符串中是否有一个
+
-
?更简单的是:它们中是否有一个可以>=10?(如果它们都是简单的ASCII数字,没有符号,没有指数符号,总是在
的左边有一个数字,那么字典排序已经将它们按正确的顺序排列了,所以你根本不需要做任何花哨的事……但是如果你必须做任何花哨的事,你最好全力以赴,使用
natsort
r。)A比试着猜测你需要重新实现多少轮子更简单…)不复杂。没有指数符号。没有负值。通常是十进制和整数。-1:这不仅会在空字符串上中断,还会按字典顺序对数字进行排序,并生成两个列表,只是为了将它们连接起来。它没有解决其他答案所能解决的任何问题,只在给出最简单输入的情况下作为正确答案发挥作用。