自然地将列表移动到字母数字值的末尾 [英] Naturally sort a list moving alphanumeric values to the end

查看:73
本文介绍了自然地将列表移动到字母数字值的末尾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要自然排序的字符串列表:

I have a list of strings I want to natural sort:

c = ['0', '1', '10', '11', '2', '2Y', '3', '3Y', '4', '4Y', '5', '5Y', '6', '7', '8', '9', '9Y']

除了自然排序外,我想将所有不是纯数字字符串的条目都移到末尾.我的预期输出是这样:

In addition to natural sort, I want to move all entries that are not pure number strings to the end. My expected output is this:

['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '2Y', '3Y', '4Y', '5Y', '9Y']

请注意,所有内容都必须进行排序-甚至是字母数字字符串.

Do note that everything has to be natsorted - even the alphanumeric strings.

我知道我可以使用natsort包来获取我想要的东西,但是仅此一项对我而言并不能做到.我需要通过两个排序调用来执行此操作-一个调用自然排序,另一个将非纯数字字符串移到末尾.

I know I can use the natsort package to get what I want, but that alone does not do it for me. I need to do this with two sort calls - one to natural sort, and another to move non-pure numeric strings to the end.

import natsort as ns
r = sorted(ns.natsorted(c), key=lambda x: not x.isdigit())

print(r)
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '2Y', '3Y', '4Y', '5Y', '9Y']

我想知道是否有可能巧妙地使用natsort并将其减少为单个排序调用.

I'd like to know if it's possible to use natsort in a crafty manner and reduce this to a single sort call.

推荐答案

您实际上可以使用natsorted和正确选择的key来执行此操作.

You can actually perform this using natsorted and the correct choice of key.

>>> ns.natsorted(d, key=lambda x: (not x.isdigit(), x))
['0',
 '1',
 '2',
 '3',
 '4',
 '5',
 '6',
 '7',
 '8',
 '9',
 '10',
 '11',
 '2Y',
 '3Y',
 '4Y',
 '5Y',
 '9Y']

键返回一个元组,其原始输入为第二个元素.数字字符串放在前面,其他所有放在后面,然后分别对子集进行排序.

The key returns a tuple with the original input as the second element. Strings that are digits get placed at the front, all others at the back, then the subsets are sorted individually.

作为旁注, Willem Van Onsem的解决方案使用natsort_key,自natsort起已弃用版本3.0.4(如果在解释器中打开DeprecationWarning,您将看到此内容,并且该函数现在尚未记录).实际上效率很低...最好使用natort_keygen返回自然排序键. natsort_key在内部调用此函数,因此对于每个输入,您都要创建一个新函数,然后调用一次.

As a side note, Willem Van Onsem's solution uses natsort_key, which has been deprecated as of natsort version 3.0.4 (if you turn on DeprecationWarning in your interpreter you will see that, and the function is now undocumented). It's actually pretty inefficient... it is preferred to use natort_keygen which returns a natural sorting key. natsort_key calls this under the hood, so for every input you are creating a new function and then calling it once.

下面,我重复此处所示的测试,然后使用natsorted方法以及使用natsort_keygen代替natsort_key的其他解决方案的时间安排.

Below I repeat the tests shown here, and I added my solution using the natsorted method as well as the timing of the other solutions using natsort_keygen instead of natsort_key.

In [13]: %timeit sorted(d, key=lambda x: (not x.isdigit(), ns.natsort_key(x)))
1 loop, best of 3: 33.3 s per loop

In [14]: natsort_key = ns.natsort_keygen()

In [15]: %timeit sorted(d, key=lambda x: (not x.isdigit(), natsort_key(x)))
1 loop, best of 3: 11.2 s per loop

In [16]: %timeit sorted(ns.natsorted(d), key=str.isdigit, reverse=True)
1 loop, best of 3: 9.77 s per loop

In [17]: %timeit ns.natsorted(d, key=lambda x: (not x.isdigit(), x))
1 loop, best of 3: 23.8 s per loop

这篇关于自然地将列表移动到字母数字值的末尾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆