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

2025-03-05 09:17:00
admin
原创
2
摘要:问题描述:我有一套set(['booklet', '4 sheets', '48 sheets', '12 sheets']) 排序后我希望它看起来像4 sheets, 12 sheets, 48 sheets, booklet 有任何想法吗解决方案 1:Jeff Atwood讨论了自然排序,并给出了在 Py...

问题描述:

我有一套

set(['booklet', '4 sheets', '48 sheets', '12 sheets'])

排序后我希望它看起来像

4 sheets,
12 sheets,
48 sheets,
booklet

有任何想法吗


解决方案 1:

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)

使用方式如下:

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

输出:

4 sheets
12 sheets
48 sheets
booklet

此方法的一个优点是它不仅适用于字符串由空格分隔的情况,还适用于其他分隔符,例如版本号中的句点(例如 1.9.1 在 1.10.0 之前)。

解决方案 2:

简短而甜蜜:

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

此版本:

  • 适用于 Python 2 和 Python 3,因为:

+ 它不假设您比较字符串和整数(这在 Python 3 中不起作用)
+ 它不使用`cmp`参数 to `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 ',
'.join(r)

解决方案 3:

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

>>> import natsort
>>> your_list = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
>>> print ',
'.join(natsort.natsorted(your_list))
4 sheets,
12 sheets,
48 sheets,
booklet

解决方案 4:

一种简单的方法是将字符串分成数字部分和非数字部分,然后使用 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)

解决方案 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)

演示:

>>> my_set = {'booklet', '4 sheets', '48 sheets', '12 sheets'}
>>> sorted(my_set, key=keyfunc)
['4 sheets', '12 sheets', '48 sheets', 'booklet']

对于 Python3 来说需要稍微修改一下(这个版本在 Python2 中也可以正常工作)

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

解决方案 6:

对字符串数组中任意位置的任意数字进行排序的通用答案。适用于 Python 2 和 3。

def alphaNumOrder(string):
   """ Returns all numbers on 5 digits to let sort the string with numeric order.
   Ex: alphaNumOrder("a6b12.125")  ==> "a00006b00012.00125"
   """
   return ''.join([format(int(x), '05d') if x.isdigit()
                   else x for x in re.split(r'(d+)', string)])

样本:

s = ['a10b20','a10b1','a3','b1b1','a06b03','a6b2','a6b2c10','a6b2c5']
s.sort(key=alphaNumOrder)
s ===> ['a3', 'a6b2', 'a6b2c5', 'a6b2c10', 'a06b03', 'a10b1', 'a10b20', 'b1b1']

部分答案就在这里

解决方案 7:

>>> a = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])
>>> def ke(s):
    i, sp, _ = s.partition(' ')
    if i.isnumeric():
        return int(i)
    return float('inf')

>>> sorted(a, key=ke)
['4 sheets', '12 sheets', '48 sheets', 'booklet']

解决方案 8:

根据 SilentGhost 的回答:

In [4]: a = set(['booklet', '4 sheets', '48 sheets', '12 sheets'])

In [5]: def f(x):
   ...:     num = x.split(None, 1)[0]
   ...:     if num.isdigit():
   ...:         return int(num)
   ...:     return x
   ...: 

In [6]: sorted(a, key=f)
Out[6]: ['4 sheets', '12 sheets', '48 sheets', 'booklet']

解决方案 9:

集合本质上是无序的。您需要创建一个具有相同内容的列表并对其进行排序。

解决方案 10:

b = set(['booklet', '10-b40', 'z94 boots', '4 sheets', '48 sheets',
         '12 sheets', '1 thing', '4a sheets', '4b sheets', '2temptations'])

numList = sorted([x for x in b if x.split(' ')[0].isdigit()],
                 key=lambda x: int(x.split(' ')[0]))

alphaList = sorted([x for x in b if not x.split(' ')[0].isdigit()])

sortedList = numList + alphaList

print(sortedList)

Out: ['1 thing',
      '4 sheets',
      '12 sheets',
      '48 sheets',
      '10-b40',
      '2temptations',
      '4a sheets',
      '4b sheets',
      'booklet',
      'z94 boots']

解决方案 11:

对于使用 Python 2.4 之前版本且没有这个出色sorted()函数的人来说,一种对集合进行排序的快速方法是:

l = list(yourSet)
l.sort() 

这并没有回答上面的具体问题(12 sheets将会在之前出现4 sheets),但对于来自 Google 的人来说可能会有用。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1324  
  IPD研发管理体系作为一种先进的研发管理理念和方法,对于打造优质产品体验起着至关重要的作用。它涵盖了从产品规划、研发、上市到生命周期管理的全流程,通过整合资源、优化流程、加强团队协作等方式,确保产品能够精准满足用户需求,提升用户满意度和忠诚度。IPD研发管理体系的核心原则IPD研发管理体系以市场驱动为核心原则。这意味着...
IPD集成产品开发   8  
  IPD(Integrated Product Development)产品开发流程作为一种先进的产品开发管理模式,在众多企业中得到广泛应用。它强调跨部门团队协作、并行工程以及基于市场的产品开发理念,旨在提高产品开发效率、缩短产品上市时间、提升产品质量。而成本控制在产品开发过程中至关重要,关乎企业的利润空间和市场竞争力。...
华为IPD流程   6  
  IPD(Integrated Product Development)产品开发流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。它从多个维度对产品开发过程进行优化和整合,为企业创新提供了强大的支撑。通过实施IPD产品开发流程,企业能够更加高效地将创意转化为具有市场竞争力的产品,从而在激烈的市场竞争中占据优...
华为IPD流程管理   10  
  华为作为全球知名的科技企业,其产品质量在市场上有口皆碑。华为IPD产品开发流程在确保产品质量方面发挥了至关重要的作用。IPD(Integrated Product Development)即集成产品开发,是一套先进的、成熟的产品开发管理思想、模式和方法。它打破了传统产品开发中各部门之间的壁垒,强调跨部门团队协作,从产品...
IPD集成产品开发流程   9  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用