【问题标题】:sort a python list while maintaining its element's indices [closed]对python列表进行排序,同时保持其元素的索引[关闭]
【发布时间】:2018-06-25 01:36:12
【问题描述】:

我需要对 python 列表进行排序,但排序不应更改元素在排序之前的索引。在 php 中有一个名为 asort 的函数,但是如何在 python 中实现呢?有没有这样的方法?如果没有,如何在更少的行中做到这一点?

举个例子:

$a = [1, 5, 2, 4];
print_r($a);
asort($a);
print_r($a);

输出将是:

Array
(
    [0] => 1
    [1] => 5
    [2] => 2
    [3] => 4
)
Array
(
    [0] => 1
    [2] => 2
    [3] => 4
    [1] => 5
)

这里 5 在asort 之后仍然有索引 1,但它已经排到了末尾。

我确实有自己的解决方案,即:将索引创建为整数列表。然后使用 [List Length] 和 [Series] 创建此列表。然后,同步对数值和索引进行排序,即使用相同的排序组件。虽然,这并不是asort() 所做的,但非常接近。

有没有更好的方法呢?那也少了几行?也许是内置方法?一种有效的方法可能比更少的行更受欢迎。

谢谢

【问题讨论】:

  • 我很困惑,asort 文档说这是用于关联数组(dicts),但您将其用于列表,那么连接是什么?
  • 请举例说明你已经尝试过什么。
  • 如何在不改变元素索引的情况下对列表进行排序?除非列表已经排序
  • @cᴏʟᴅsᴘᴇᴇᴅ 在 PHP 中,数组既用作数字索引列表 也用作 关联字典。
  • @deceze 谢谢。这些是应该来自 OP 的重要细节。这个真的不清楚……

标签: python sorting asort


【解决方案1】:

PHP 和 Python 之间的主要区别在于 PHP 数组是关联数组和有序数组,而在 Python 中,您可以有一个 ordered list 一个 关联 dict,但不能同时在一个数据结构中。*

* OrderedDictdict 开始自行排序,但让我们坚持使用原语。

所以从根本上说,您需要考虑不同的数据结构。执行此操作的典型方法是创建一个元组列表,其中一个元组值表示您以前的索引,另一个值表示以前的值:

[(0, 'foo'), (1, 'bar'), ...]

您可以使用enumerate从普通列表中获取:

l = list(enumerate(my_list))  # ['foo', 'bar'] → [(0, 'foo'), (1, 'bar')]

而且你可以在这个过程中对其进行排序:

l = sorted(enumerate(my_list), key=lambda i: i[1])  # → [(1, 'bar'), (0, 'foo')]

这里lambda i: i[1] 只是按第二个元组值排序,即你以前的值。为简洁起见,您可以将其替换为 operator 模块中的 itemgetter(1),或根据您的排序条件进行调整。

如果您想再次将其转换为关联数据结构,请使用OrderedDict

from collections import OrderedDict
from operator import itemgetter

l = OrderedDict(sorted(enumerate(my_list), key=itemgetter(1)))

【讨论】:

  • 好的,我明白你在说什么。我想接受答案,但我可能需要看几件事。给我一点时间
  • 好吧,伙计。这很有意义。
【解决方案2】:

首先将原始值连接到其索引列表。然后对它进行排序,原始索引将附加到新的排序值。最后解压缩它们以获取两个列表。

i_xs                 = [(x, i) for (i, x) in enumerate(xs)]
s                    = sorted(i_xs)
sorted_xs, index_lst = unzip(s)

使用这个

def unzip(ls):
    if isinstance(ls, list):
        if not ls:
            return [], []
        else:
            xs, ys = zip(*ls)

        return list(xs), list(ys)
    else:
        raise TypeError

示例。在:

[34, 23424, 1212, -2324, 34353]

输出:

[-2324, 34, 1212, 23424, 34353]

[3, 0, 2, 1, 4]

【讨论】:

    猜你喜欢
    • 2021-03-17
    • 2022-11-26
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 2014-01-27
    相关资源
    最近更新 更多