Python按名称排序

时间:2012-09-30 04:01:59

标签: python

我尝试使用已排序的

进行排序
dir =["A1","A2","A10","A3"]
sorted(dir)

我期望的数组是

["A1","A2","A3","A10"]

但实际结果是

["A1", "A10", "A2", "A3"]

如何在python中按名称排序数组?

2 个答案:

答案 0 :(得分:5)

按字母顺序排序,因此您需要分解数字并将其转换为整数并按此排序。 (字符串中的数字只被视为字符,因此它“看到”“A10”并尝试先按“A”排序,然后按“1”,再按“0”排序。例如:

>>> sorted(dir, key=lambda x: int(x[1:]))
['A1', 'A2', 'A3', 'A10']

如果你要在dir中除了“A”之外还有其他字母,你需要一个更复杂的排序方法,但它将是同样的东西。 (如果你解释dir包含更多内容,我可以为此写一个例子。)正如mgilson的评论指出的那样,如果dir的元素遵循1 char +数字格式,那么你可以利用元组排序和做这样的事情:

>>> dir.append('B12')
>>> sorted(dir, key=lambda x: (x[0],int(x[1:])))
['A1', 'A2', 'A3', 'A10', 'B12']

答案 1 :(得分:0)

要扩展这个问题,我必须自然地对接口名称进行排序。使接口更加复杂的是,接口可以具有多种风格……您拥有传统的接口,例如loeth0等……以及一些更高级的方案,例如{{1} }。解决方案是根据类型对它们进行拆分,将数字转换为int,并且必须注意确保在相同类型上进行比较。

所以我想出了这个排序函数,该函数应该相当防弹(只要您给它提供字符串...)

enp4s0f1d1

它可以这样使用:

def ethkey(eth):
    """Split an ethernet device name between text and digit groups as int,
    allowing consistent sorting of interfaces.

    Usage: `sorted(if_list, key=ethkey)`

    :param eth: Value to sort
    :type eth: str
    :return: List of str's (even indexes) and int's (odd indexes) to compare
    :rtype: list
    """

    keys = []
    if not eth:
        # If eth is a string it's empty, just return blank list
        return keys

    # Start with the first character already in last
    last, eth = eth[0], eth[1:]
    # If last is int we start at offset 1
    if last.isdigit():
        keys.append('')

    for i in eth:
        if i.isdigit() is last.isdigit():
            # Keep accumulating same type chars
            last += i
        else:
            # Save and restart next round
            keys.append(int(last) if last.isdigit() else last)
            last = i

    # Save final round and return
    keys.append(int(last) if last.isdigit() else last)
    return keys