在 Python 中按元组的第一个元素自然地对字母数字元组列表进行排序

发布于 2024-11-26 16:00:32 字数 501 浏览 1 评论 0原文

上一个 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。

A previous stackoverflow question explains how to sort a list of strings alpha-numerically. I would like to sort a list of tuples alphanumerically by the tuple's first element.

Example 1:

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

Example 2:

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

Update: To emphasize the alphanumeric factor, please review example 2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冷血 2024-12-03 16:00:32

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

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。

Using the second answer from the other question, generalized to support any method on item as the basis for getting the key:

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))

This is exactly the same as that answer except generalized to use any callable as the operation on item. If you just wanted to do it on a string, you'd use lambda item: item, if you wanted to do it on a list, tuple, dict, or set, you'd use operator.itemgetter(key_or_index_you_want), or if you wanted to do it on a class instance you could use operator.attrgetter('attribute_name_you_want').

It gives

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

for your example #2.

笑,眼淚并存 2024-12-03 16:00:32

默认情况下,元组按其元素排序,从第一个元素开始。因此,只需做

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]))

Tuples are by default sorted by their elements, starting at the first. So simply do

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)])

The question you liked to talks about natural sorting, which is different from normal (alphanumeric) sorting.

Lets say you want to do natural sort on the first item only:

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]))
拥有 2024-12-03 16:00:32

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

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])

As others have pointed out, sorted will use the first element of the tuple by default. If you wish to modify this default behavior you can specify a key to be used during the comparisons.

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

Will return the same as:

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

To sort by the second element however try:

sorted([('b', 0), ('0', 1), ('a', 2)], key=lambda item: item[1])
—━☆沉默づ 2024-12-03 16:00:32

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)]

The natsort module does this by default without any extra work

>>> 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)]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文