【问题标题】:Sorting alphanumeric sequences is not correct. How can I improve it? [duplicate]对字母数字序列进行排序不正确。我该如何改进它? [复制]
【发布时间】:2015-04-18 05:17:18
【问题描述】:

当我尝试这个时,我无法得到我想要的结果 -

>>> test = { '3 Silver', '3 Oct', '4AD', '99 Reese', '1991', 'alpha', 'beta' }
>>> sorted(test)
['1991', '3 Oct', '3 Silver', '4AD', '99 Reese', 'alpha', 'beta']

这是不正确的,因为1991 是以数字开头的最高条目,应该出现在alpha 之前

有没有人对我如何按照我想要的方式进行排序有任何建议?

【问题讨论】:

  • 你想得到什么结果?
  • 搜索“自然排序”。
  • @JeremyBanks 他希望将“1991”移到“alpha”之前。
  • @user1692999 这个其他帖子应该是你要找的。 :) 如果不是,请告诉我。
  • 你能输入你的预期输出吗?您的预期列表是什么样的?

标签: python sorting dictionary alphanumeric


【解决方案1】:

如果您想首先考虑数值来对项目进行排序(有一些边缘情况需要考虑,但应该指出正确的方向):

from itertools import takewhile, dropwhile

test = ['3 Silver', '3 Oct', '4AD', '99 Reese', '1991', 'alpha', 'beta']

items = dict()
for word in test:
    ordlist  = []
    ## prenumber will be zero if there are no numerical characters
    prenumber = int(''.join(list(takewhile(lambda i: i.isdigit() , word))) or 0)
    ## setting words that start with alpha characters to have infinity as 
    ## first item. This puts them at the end of the list for sorting. 
    ordlist.append(prenumber or float("inf"))
    ordlist.extend((ord(ch) for ch in dropwhile(lambda i: i.isdigit(), word)))
    items[word] = ordlist

### sort dictionary by value
s = sorted(zip(items.values(), items.keys()))
print(s)
## [([3, 32, 79, 99, 116], '3 Oct'),
##    ([3, 32, 83, 105, 108, 118, 101, 114], '3 Silver'),
##    ([4, 65, 68], '4AD'),
##    ([99, 32, 82, 101, 101, 115, 101], '99 Reese'),
##    ([1991], '1991'),
##    ([inf, 97, 108, 112, 104, 97], 'alpha'),
##    ([inf, 98, 101, 116, 97], 'beta')]

test_sorted = [e[1] for e in s]
## ['3 Oct', '3 Silver', '4AD', '99 Reese', '1991', 'alpha', 'beta']

【讨论】:

  • 这很好用,谢谢!但它会删除重复的条目,因此输出与输入的项目数不一定相同。
【解决方案2】:

是的,您可以这样做,但您必须创建自己的“评分”系统,以创建您想要的订单:

import re

def score(token):
    n = re.sub(r'\D+', '', token)
    if n:
        n = int(n)
    w = re.sub(r'[\d+ ]', '', token)
    return n, w #returning a list/tuple with the most important criteria on the first place, 2nd on the second place, etc



arr = ['3 Silver', '3 Oct', '4AD', '99 Reese', '1991', 'alpha', 'beta']
print sorted(arr, key=score) # ['3 Oct', '3 Silver', '4AD', '99 Reese', '1991', 'alpha', 'beta']

【讨论】:

  • 感谢您的建议,但这不是您描述的所有规则,我可以看到您在这里最多只能捕获 4 个数字。
  • @user1692999 我刚刚学会了这个新技巧:返回一个列表/元组,其中最重要的标准放在第一位,第二位放在第二位等等 - 会给你你想要的非常优雅的方式,而不会限制您对输入的某些限制。请参阅上面更新的score() 函数!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-07
  • 2013-06-20
  • 2017-01-17
  • 1970-01-01
  • 2018-05-04
  • 2019-07-01
相关资源
最近更新 更多