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

2025-03-05 09:17:00
admin
原创
4
摘要:问题描述:我有一套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 的人来说可能会有用。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1325  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。它涵盖了从产品概念产生到产品退市的整个生命周期,通过整合跨部门团队、优化流程等方式,显著提升产品开发的效率和质量,进而为项目的成功奠定坚实基础。深入探究IPD流程的五个阶段与项目成功之间...
IPD流程分为几个阶段   4  
  华为作为全球知名的科技企业,其成功背后的管理体系备受关注。IPD(集成产品开发)流程作为华为核心的产品开发管理模式,其中的创新管理与实践更是蕴含着丰富的经验和深刻的智慧,对众多企业具有重要的借鉴意义。IPD流程的核心架构IPD流程旨在打破部门墙,实现跨部门的高效协作,将产品开发视为一个整体的流程。它涵盖了从市场需求分析...
华为IPD是什么   3  
  IPD(Integrated Product Development)研发管理体系作为一种先进的产品开发模式,在众多企业的发展历程中发挥了至关重要的作用。它不仅仅是一套流程,更是一种理念,一种能够全方位提升企业竞争力,推动企业持续发展的有效工具。深入探究IPD研发管理体系如何助力企业持续发展,对于众多渴望在市场中立足并...
IPD管理流程   3  
  IPD(Integrated Product Development)流程管理旨在通过整合产品开发流程、团队和资源,实现产品的快速、高质量交付。在这一过程中,有效降低成本是企业提升竞争力的关键。通过优化IPD流程管理中的各个环节,可以在不牺牲产品质量和性能的前提下,实现成本的显著降低,为企业创造更大的价值。优化产品规划...
IPD流程分为几个阶段   4  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用