对 Python 列表进行排序,同时维护其元素的索引



>我需要对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,但它已被排序到最后。

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

有没有更好的方法?那也少行了?也许是内置方法?与更少的线路相比,可以首选有效的方法。

谢谢

PHP和 Python 之间的主要区别在于 PHP 数组既是关联数组又是有序数组,而在 Python 中,你可以有一个有序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)))

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

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]

相关内容

  • 没有找到相关文章

最新更新