【问题标题】:Python - how to find the position of the second lowest value in a list [duplicate]Python - 如何找到列表中第二低值的位置[重复]
【发布时间】:2018-05-08 20:11:26
【问题描述】:

我有以下清单:

list = [7,3,6,4,6]

我知道我可以使用list.index(min(list)) 来查找列表中最小数字的位置,但是如何使用它来查找第二最低的?

【问题讨论】:

  • 这比欺骗提议要复杂一些。例如,在这里使用 heapq 不符合条件,因为您必须关联索引,而不仅仅是值。
  • 我什至不明白,像alist = [7, 3, 6, 4, 6, 3] 这样的上下文中的“第二低值”是什么意思。预期输出是后三还是四?
  • 不是重复的。但是没有重新打开,因为它得到了足够的答案:)
  • @Piinthesky 不确定 OP 是否考虑过这一点(或者该死的)。

标签: python list


【解决方案1】:

不要使用列表作为变量名

编辑,最初被误读为第二高的索引 - 现在已修复,thanx Jean-François Fabre

lst = [7,3,6,4,6]

lst.index(sorted(lst)[1])

Out[161]: 3

lst[3]
Out[162]: 4

sorted(lst)
Out[163]: [3, 4, 6, 6, 7]

上面有输入列表中重复数字的问题,通过使用.index可以得到第一个匹配的索引

lst = [1, 1, 7,3,6,4,6]

lst.index(sorted(lst)[1])
Out[9]: 0                  # 0 is wrong, the postion of the 2nd smallest is 1  

我认为这可以解决问题

n = 1
sorted([*enumerate(lst)], key=lambda x: x[1])[n][0]
Out[11]: 1  

看碎片

[*enumerate(lst)]
Out[12]: [(0, 1), (1, 1), (2, 7), (3, 3), (4, 6), (5, 4), (6, 6)]

enumerate 将计数与输入 lst 中的值配对,* 强制“解包”枚举对象,外部方括号在 list 中“捕获”此输出

在 Python 内置 sorted 中,第二个参数 key=lambda x: x[1] 告诉它查找来自 [*enumerate(lst)] 的元组的第二个位置,它们是来自 lst 的数字

sorted([*enumerate(lst)], key=lambda x: x[1])
Out[13]: [(0, 1), (1, 1), (3, 3), (5, 4), (4, 6), (6, 6), (2, 7)]  

使用[n][0] 对列表进行索引获取第n 个排序的元组,并从元组中获取第一个值,即enumerate 中指定的索引

【讨论】:

  • 返回数字 2 - 这是什么意思?
  • 答案不正确 -2 应该是 1 来选择第二低的,而不是最高的。
  • 读错了,是的,索引按 1 排序为第二低,已修复
  • @f5r5e5d 只是出于兴趣,如果我把其他数字放在最后的方括号中,他们会怎么做?例如,我如何找到第三个最低值?
【解决方案2】:

试试这个:

list.index(sorted(list)[1])

【讨论】:

  • 每个部分的作用是什么?
  • 哎呀抱歉:排序只是按升序对您的列表进行排序。所以你知道在我们的例子中你的第二低将位于第二个位置“1”。这就是为什么我把“sorted(list)[1]”放到它的值上。然后 list.index(value) 将为您提供列表中元素的索引。对不起,迟到的回答家伙!
  • 此解决方案与您尝试检索的索引相混淆。如果您需要原始列表中的完整索引,请使用所选答案。
  • @dmoz 真的吗?如何?排序不像排序。
  • 因为sorted 创建了一个带有新索引的新列表,不是吗?如果这就是你要找的,很好,但如果你需要原始索引,那么接受的答案可能会更好,对吧?
【解决方案3】:

您可以根据值对enumerated 列表进行排序,然后选择第二项。

def second_pos(numbers):
    return sorted(enumerate(numbers),key=lambda x:x[::-1])[1][0]

print(second_pos([7,3,6,4,6]))

结果:3,因为 4 是第二低的值

这个解决方案只涉及一个sort操作,之后没有index操作来查找索引,保存最后一个O(n)操作。

请注意,如果 2 个值相等,则有一个决胜局选择最低位置的项目。

还要注意,如果列表太小,你可以得到一个IndexError

【讨论】:

    【解决方案4】:

    使用set 删除重复项,像这样

    lowest_nth = 2
    lst.index(sorted(set(lst))[lowest_nth-1])
    

    编辑(重要说明):

    如果您尝试使用此代码,如果不使用 set,则会看到错误的结果并包含重复值:

    lst = [7, 6, 6, 4, 3, 8]
    
    def get_index_without_using_set():
        return lst.index(sorted(lst)[lowest_nth-1])
    
    def get_index_using_set():
        return lst.index(sorted(set(lst))[lowest_nth-1])
    
    print(lst)
    print()
    print('Without set:')
    for lowest_nth in range(1,6):
        print('lowest {}: {}'.format(lowest_nth, get_index_without_using_set()))
    
    print()
    print('With set:')
    for lowest_nth in range(1,6):
        print('lowest {}: {}'.format(lowest_nth, get_index_using_set()))
    
    
    Output:
    
    [7, 6, 6, 4, 3, 8]
    
    Without set:
    lowest 1: 4
    lowest 2: 3
    lowest 3: 1
    lowest 4: 1  <-- wrong index, see below
    lowest 5: 0
    
    With set:
    lowest 1: 4
    lowest 2: 3
    lowest 3: 1
    lowest 4: 0
    lowest 5: 5
    

    【讨论】:

    • 但这不会破坏索引吗?
    • set(lst) 创建一个新对象,不触及原始lst。实际上它破坏了该对象中的索引,但sorted 再次创建了一个有序列表。我还没有索引,只是集合中最低的第 n 个值。然后lst.index 方法给出该值所需的索引结果。
    • 好的,我的评论是正确的?到底。没错。
    • 检查我的编辑@Jean
    • 这是因为 OP 没有为等值定义任何策略。你的回答很好。
    【解决方案5】:

    这似乎很合适:

    def find_2nd_smallest(iterable):
        try:
            st = set(iterable)
            st.discard(min(st))
            return iterable.index(min(st))
        except:
            return None
    
    my_list = [7,3,6,4,6]
    print (find_2nd_smallest(my_list))
    

    打印第二个最小的第一次出现的索引:

    3
    

    如果您想要一个可以输入最小数字的函数(2 表示第二小):

    def find_nth_smallest(iterable,n):
        try:
            st = set(iterable)
            for i in range(n-1):
                st.discard(min(st))
            return iterable.index(min(st))
        except: return None
    
    my_list = [7,3,6,4,6]
    print (find_nth_smallest(my_list,2))
    

    请注意,这些功能可能不是最有效的解决方案。

    【讨论】:

      【解决方案6】:

      您可以只删除 min ,然后获取具有新 min 的新列表的 min ,这将是第二个 min 。我复制了一份清单,这样它就可以工作,但可能不需要这样做。

      lst_copy = list(lst)
      lst.remove(min(lst))
          lst_copy.index(min(lst))
      

      【讨论】:

      • 这不像书面的那样工作 - .remove() 修改列表,并返回无。不过,基本思想是有效的。
      • list(list): 这不行:)
      • 我只是使用列表函数-docs.python.org/2/library/functions.html#list,变量是列表。为什么它不起作用。
      • 因为python不能把两个东西(函数和变量)同名关联起来。这就是为什么不应该将事物命名为与内置函数相同的原因。 (我知道它在 OP 中,但你应该改变它)
      • ok 改成 lst
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多