如何在python中对字母数字集进行排序

mmr*_*151 61 python sorting

我有一套

set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
Run Code Online (Sandbox Code Playgroud)

排序后我希望它看起来像

4 sheets,
12 sheets,
48 sheets,
booklet
Run Code Online (Sandbox Code Playgroud)

请问任何想法

Mar*_*ers 102

Jeff Atwood谈到自然排序,并举例说明了在Python中实现它的一种方法.这是我的变化:

import re 

def sorted_nicely( l ): 
    """ Sort the given iterable 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) ] 
    return sorted(l, key = alphanum_key)
Run Code Online (Sandbox Code Playgroud)

使用这样:

s = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
for x in sorted_nicely(s):
    print(x)
Run Code Online (Sandbox Code Playgroud)

输出:

4 sheets
12 sheets
48 sheets
booklet
Run Code Online (Sandbox Code Playgroud)

这种方法的一个优点是,当字符串被空格分隔时,它不仅起作用.它也适用于其他分隔符,例如版本号中的句点(例如1.9.1在1.10.0之前).

  • 此功能区分大小写.大写字符串优先.要解决此问题,请在`re.split`中将`.lower()`添加到`key`. (3认同)
  • 是否可以根据元组中的第一个值修改元组列表?示例:`[('b',0),('0',1),('a',2)]`被排序为`[('0',1),('a',2), ('b',0)]` (2认同)

Dan*_*ach 56

短而甜蜜:

sorted(data, key=lambda item: (int(item.partition(' ')[0])
                               if item[0].isdigit() else float('inf'), item))
Run Code Online (Sandbox Code Playgroud)

这个版本:

  • 适用于Python 2和Python 3,因为:
    • 它不假设你比较字符串和整数(这在Python 3中不起作用)
    • 它不使用cmp参数sorted(Python 3中不存在)
  • 如果数量相等,将对字符串部分进行排序

如果您想要完全按照示例中的描述打印输出,那么:

data = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
r = sorted(data, key=lambda item: (int(item.partition(' ')[0])
                                   if item[0].isdigit() else float('inf'), item))
print ',\n'.join(r)
Run Code Online (Sandbox Code Playgroud)


Set*_*ton 14

你应该看看第三方库natsort.它的算法是通用的,因此它适用于大多数输入.

>>> import natsort
>>> your_list = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
>>> print ',\n'.join(natsort.natsorted(your_list))
4 sheets,
12 sheets,
48 sheets,
booklet
Run Code Online (Sandbox Code Playgroud)


Ant*_*sma 8

一种简单的方法是将字符串拆分为数字部分和非数字部分,并使用python元组排序顺序对字符串进行排序.

import re
tokenize = re.compile(r'(\d+)|(\D+)').findall
def natural_sortkey(string):          
    return tuple(int(num) if num else alpha for num, alpha in tokenize(string))

sorted(my_set, key=natural_sortkey)
Run Code Online (Sandbox Code Playgroud)


Joh*_*ooy 5

有人建议我在这里重新发布此答案,因为它在这种情况下也很好用

from itertools import groupby
def keyfunc(s):
    return [int(''.join(g)) if k else ''.join(g) for k, g in groupby(s, str.isdigit)]

sorted(my_list, key=keyfunc)
Run Code Online (Sandbox Code Playgroud)

演示:

>>> my_set = {'booklet', '4 sheets', '48 sheets', '12 sheets'}
>>> sorted(my_set, key=keyfunc)
['4 sheets', '12 sheets', '48 sheets', 'booklet']
Run Code Online (Sandbox Code Playgroud)

对于Python3,有必要对其进行一些修改(此版本在Python2中也可以正常使用)

def keyfunc(s):
    return [int(''.join(g)) if k else ''.join(g) for k, g in groupby('\0'+s, str.isdigit)]
Run Code Online (Sandbox Code Playgroud)