【问题标题】:Python: Finding the last index of min element?Python:找到最小元素的最后一个索引?
【发布时间】:2013-07-30 22:18:49
【问题描述】:

例如 [1,2,3,4,1,2]

有最小元素 1,但它最后一次出现在索引 4。

【问题讨论】:

    标签: python list min


    【解决方案1】:
    a = [1,2,3,4,1,2]
    
    a.reverse()
    print len(a) - a.index(min(a)) - 1
    

    评论后更新:

    可以通过再次反转来消除副作用(但当然这是非常低效的)。

    a.reverse()
    

    【讨论】:

    • 这也有把他的名单倒过来的副作用
    【解决方案2】:
    >>> from operator import itemgetter
    >>> from itertools import izip,count
    >>> min(izip(count(len(L)-1,-1), reversed(L)), key=itemgetter(1))[0]
    4
    

    说明

    reversed 返回遍历原始列表而不创建临时列表的迭代器:

    >>> reversed(L)
    <listreverseiterator object at 0x00E823B0>
    

    izipcount 是懒惰的,而且似乎没有字节码执行,所以我希望这个解决方案非常快,而且是单行的。


    时间比较

    http://ideone.com/ZQuge3

    使用index 的解决方案被证明是最快的,尽管它们必须通过列表 2 次。其他解决方案在每次迭代时都会在生成器中创建辅助元组,我认为这就是这些解决方案速度较慢的原因。甚至 akson128 调用字节码执行的解决方案仍然更快(因为它不必创建元组)。

    【讨论】:

      【解决方案3】:
      len(myList)-1 - myList[::-1].index(min(list))
      

      这使用切片符号list[::-1] 返回反向列表的浅表副本,这样它就不会更改您的原始列表,然后搜索该列表中的最小值

      >>>myList = [1,2,3,4,1,2]
      >>>len(myList)-1 - myList[::-1].index(min(list))
      4
      

      【讨论】:

        【解决方案4】:
        >>> values = [1,2,3,4,1,2]
        >>> -min((x, -i) for i, x in enumerate(values))[1]
        4
        

        不修改原始列表,适用于任意迭代,只需要一次。

        这将创建一个可迭代的元组,其中第一个值是列表中的原始元素,第二个元素是否定索引。当在这个元组的可迭代中找到最小值时,将首先比较值,然后是索引,因此您最终将得到一个 (min_value,lowest_negative_index) 的元组。通过从这个元组中取出第二个元素并再次否定它,您可以获得最小值的最高索引。

        这是一个非常相似的替代版本,但使用了min()的键功能:

        >>> min(range(len(values)), key=lambda i: (values[i], -i))
        4
        

        请注意,此版本仅适用于序列(列表、元组、字符串等)。

        【讨论】:

        • 我认为您的第二个解决方案可以通过在每次比较时不分配元组来受益:min(range(len(values)), key=lambda i: values[i]-i)
        • @ovgolovin 有趣的计时结果,我有点惊讶我的版本比其他版本慢一些。枚举或生成器表达式的开销一定比我意识到的要多。此外,您对第二个解决方案的修改并不总是给出正确的答案,请考虑列表[0, 2, 2, 2, 1]。你会得到4 作为结果,即使它不是列表中最小的。
        • 我认为速度问题归结为元组创建。请参阅我最近关于此主题的问题(非常不明显):stackoverflow.com/questions/17640235/…
        【解决方案5】:

        效率不高(我是 Python 的初学者),但也能正常工作。 idx 将只保存最小元素的最后一个索引。我认为 M.Keijzers 方法是最好的。

        array = [1,2,3,4,1,2]
        min_val = min(array) 
        for i in range(len(array)):
            if array[i] == min_val:
                idx = i
        
        print idx
        

        【讨论】:

          【解决方案6】:

          len(list_) - list_[::-1].index(min(list_)) - 1

          获取列表的长度,减去反向列表中列表的最小值的索引,然后减去1。

          【讨论】:

            猜你喜欢
            • 2021-04-20
            • 2021-10-31
            • 1970-01-01
            • 2016-07-14
            • 1970-01-01
            • 2018-05-20
            • 2012-12-17
            • 1970-01-01
            • 2011-06-25
            相关资源
            最近更新 更多