【问题标题】:Ranking list in ascending order but keeping the index same按升序排列列表但保持索引不变
【发布时间】:2021-07-30 08:40:12
【问题描述】:

我有一个数字列表,我想按升序排列,但它们的索引很重要,我想保持它们不变。

例如:

index 0  1 2 3  4  5  6 7 8  9

a =  [22,2,4,53,43,32,3,5,1,101] 

到:

index  8 1 6 2 7  0  5 4  3   9
a =   [1,2,3,4,5,22,32,43,53,101] 

如何排列它们?

谢谢

【问题讨论】:

  • indexes, values = zip(*sorted(enumerate(a), key=itemgetter(1))) 进口:itemgetter().
  • @OlvinR​​oght 谢谢人做得很好!

标签: python arrays list


【解决方案1】:

基本上,我的回答是对Alex 的补充在我离开this 评论后 2 分钟发布

有一个内置的enumerate() 函数,它产生索引元组和迭代中每个项目的值,你可以将它的结果直接传递给sorted()itemgetter(1) 作为key 参数。它将返回元组列表 (index, value) 按第二个元素 (即 value) 排序。

要从对列表中获取两个单独的列表,您可以将列表解压缩到 zip() 并将结果分配给两个单独的变量。

代码:

from operator import itemgetter

a = [1,2,3,4,5,22,32,43,53,101]
indexes, values = zip(*sorted(enumerate(a), key=itemgetter(1)))

【讨论】:

    【解决方案2】:

    您可以将列表重新创建为(index, value) 的元组列表:

    >>> arr = list(enumerate(a))
    >>> arr
    [(0, 22),
     (1, 2),
     (2, 4),
     (3, 53),
     (4, 43),
     (5, 32),
     (6, 3),
     (7, 5),
     (8, 1),
     (9, 101)]
    

    然后,您可以按原始索引或使用0 作为索引和1 作为值的值来排序:

    >>> sorted(arr, key=lambda x: x[1])
    [(8, 1),
     (1, 2),
     (6, 3),
     (2, 4),
     (7, 5),
     (0, 22),
     (5, 32),
     (4, 43),
     (3, 53),
     (9, 101)]
    

    或者按照@Olvin Roght的建议使用itemgetter

    >>> from operator import itemgetter
    >>> sorted(arr, key=itemgetter(1))
    

    【讨论】:

      【解决方案3】:

      根据定义,列表中元素的索引是它在列表中的位置。 如果要保留原始索引作为信息,可以将列表的元素更改为长度为 2 的元组/列表,以第一个元素为值,索引为第二个元素。

      a = [1,2,3,4,5,22,32,43,53,101]
      
      # adding original index to each element
      for i in range(len(a)):
          a[i] = (a[i],i)
      
      # sorting the list based on the first number in each element
      def compare(x):
          return -x[0]
      a.sort(key=compare)
      
      print(a)
      

      编辑:根据 cmets 和其他答案的建议,您可以使用内置函数和更紧凑的语法替换一些代码:

      • 您可以使用enumerate 构造函数来枚举列表,然后使用list 构造函数从对象创建一个列表
      • 您可以将比较函数替换为紧凑的 lambda。喜欢lambda x : x[1] 虽然我通常会在编写代码时进行这些更改,但我尽量让代码简单易懂,以防您不熟悉上述某些功能。

      【讨论】:

      • 您正在重新实现内置的 enumerate()operator.itemgetter() 函数。此外,如果您想以相反的顺序对元素进行排序,reversed 函数中有 list.sort() 参数。
      • 这是一个糟糕的答案,正如已经提到的,您应该使用built-in functions
      • @Alex,还不错,只是某些部分可以被内置函数替换和/或改进。
      • 抱歉,我只是想让答案尽可能简单易懂
      • @OlvinR​​oght,内置函数可以使用,因为它们使推理代码在做什么更容易。通过使用循环覆盖列表和自定义比较函数,这个 sn-p 掩盖了正在发生的事情。
      猜你喜欢
      • 2023-01-09
      • 1970-01-01
      • 2014-08-20
      • 2017-02-13
      • 2023-03-30
      • 2018-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多