4

上一个stackoverflow 问题解释了如何按字母数字对字符串列表进行排序。我想按元组的第一个元素按字母数字对元组列表进行排序。

示例 1:

>>> sort_naturally_tuple([('b', 0), ('0', 1), ('a', 2)])
[('0', 1), ('a', 2), ('b', 0)]

示例 2:

>>> sort_naturally_tuple([('b10', 0), ('0', 1), ('b9', 2)])
[('0', 1), ('b9', 2), ('b10', 0)]

更新: 为了强调字母数字因素,请查看示例 2。

4

4 回答 4

5

使用另一个问题的第二个答案,泛化为支持项目上的任何方法作为获取密钥的基础:

import re
from operator import itemgetter

def sorted_nicely(l, key):
    """ Sort the given iterable in the way that humans expect."""
    convert = lambda text: int(text) if text.isdigit() else text
    alphanum_key = lambda item: [ convert(c) for c in re.split('([0-9]+)', key(item)) ]
    return sorted(l, key = alphanum_key)


print sorted_nicely([('b10', 0), ('0', 1), ('b9', 2)], itemgetter(0))

这与那个答案完全相同,只是广义上使用任何可调用作为对项目的操作。如果你只是想在一个字符串上做,你会使用lambda item: item,如果你想在列表、元组、字典或集合上做,你会使用operator.itemgetter(key_or_index_you_want),或者如果你想在类实例上做可以使用operator.attrgetter('attribute_name_you_want').

它给

[('0', 1), ('b9', 2), ('b10', 0)]

对于您的示例#2。

于 2011-07-27T18:24:47.633 回答
4

默认情况下,元组按其元素排序,从第一个开始。所以简单地做

L = [('b', 0), ('0', 1), ('a', 2)]
L.sort()
print L
# or create a new, sorted list
print sorted([('b', 0), ('0', 1), ('a', 2)])

你喜欢谈论的问题是自然排序,它不同于普通的(字母数字)排序。

假设您只想对第一项进行自然排序:

import re
def naturalize(item):
    # turn 'b10' into ('b',10) which sorts correctly
    m = re.match(r'(\w+?)(\d+)', item)
    return m.groups()
# now sort by using this function on the first element of the tuple:
print sorted(L, key=lambda tup: naturalize(tup[0]))
于 2011-07-27T18:06:14.020 回答
1

正如其他人指出的那样, sorted 默认情况下将使用元组的第一个元素。如果您希望修改此默认行为,您可以指定要在比较期间使用的键。

sorted([('b', 0), ('0', 1), ('a', 2)])

将返回与以下内容相同:

sorted([('b', 0), ('0', 1), ('a', 2)], key=lambda item: item[0])

但是,要按第二个元素排序,请尝试:

sorted([('b', 0), ('0', 1), ('a', 2)], key=lambda item: item[1])
于 2011-07-27T18:09:52.360 回答
0

natsort模块默认执行此操作,无需任何额外工作

>>> from natsort import natsorted
>>> natsorted([('b', 0), ('0', 1), ('a', 2)])
[('0', 1), ('a', 2), ('b', 0)]
>>> natsorted([('b10', 0), ('0', 1), ('b9', 2)])
[('0', 1), ('b9', 2), ('b10', 0)]
于 2015-01-15T04:08:35.627 回答