代码之家  ›  专栏  ›  技术社区  ›  piripiri

求最小元素及其在无元素列表中的位置

  •  4
  • piripiri  · 技术社区  · 7 年前

    我有一张号码表 None 像这样:

    l = [2., None, 3., 1., None, 2., None, 5.]
    

    我想得到最小数及其索引,而 没有 S应该被忽略。对于给定的示例,结果将是:

    (1., 3)
    

    当然,编写一个满足我需求的函数是很简单的,但我更喜欢一些高效的内置方法或至少是高级方法。 我对python 3的解决方案特别感兴趣,其中 min -函数不接受 没有 作为论据。

    9 回复  |  直到 7 年前
        1
  •  4
  •   DYZ    7 年前
    min((v,i) for i,v in enumerate(l) if v is not None)
    (1.0, 3) # (value, index)
    
        2
  •  3
  •   pstatix    7 年前

    我可能会分两部分:

    m = min(x for x in l if x is not None)
    s = (m, l.index(m)) # this will grab the first index
    

    如果要使列表成为单通道+一行解决方案:

    midx, mval = min(enumerate(x if x is not None else float('inf') for x in l), key=lambda i: i[1])
    

    这个 enumerate() 一件作品产生了一种类似于:

    0 2.0
    1 inf
    2 3.0
    3 1.0
    4 inf
    5 2.0
    6 inf
    7 5.0
    

    然后 min() 被调用并使用 枚举() 返回 lambda 检查 i[1] 索引(例如) 2.0, inf, ..., 5.0 )因此,最后一个元组只返回一次迭代,使用原始列表中的生成器来“过滤并替换” NoneType 指数。

        3
  •  3
  •   jpp    7 年前

    您可以定义转换函数并将其与 min :

    lst = [2., None, 3., 1., None, 2., None, 5.]
    
    def converter(x):
        return x[1] if x[1] is not None else float('inf')
    
    res = min(enumerate(lst), key=converter)[::-1]
    
    (1.0, 3)
    

    如果您很乐意使用第三方库,在Numpy中相当于:

    arr = np.array(lst).astype(float)
    arr[np.isnan(arr)] = np.inf
    
    res = arr.min(), arr.argmin()
    

    或者,更有效地,你可以使用 np.nanargmin :

    arg = np.nanargmin(arr)
    minval = arr[arg]
    
    res = minval, arg
    
        4
  •  1
  •   Druta Ruslan    7 年前
    l = [2., None, 3., 1., None, 2., None, 5.]
    
    idx = l.index(min(x for x in l if x is not None))
    
    print(l[idx], idx) # get value, and idx
    

    产量

    1.0 3
    
        5
  •  0
  •   cmitch    7 年前

    value = min(l, key=lambda x: float('inf') if x is None else x) index = l.index(value)

    如果这是一个问题,可能包括一个值不是inf的检查(例如,在l中没有数字的情况下)

    此方法通过简单地更改min比较值的方式,避免在内部构造新数组。

        6
  •  0
  •   Rakesh    7 年前

    这是一种方法。

    演示:

    l = [2., None, 3., 1., None, 2., None, 5.]
    l = [(v, i) for i, v in enumerate(l) if v is not None]
    print( sorted(l, key=lambda x: x[0])[0] )
    

    输出:

    (1.0, 3)
    
        7
  •  0
  •   Paul Panzer    7 年前

    你可以避免使用 key 像这样:

    >>> import operator as op
    >>> import itertools as it
    >>> min(it.filterfalse(op.methodcaller('__contains__', None), zip(l, it.count())))
    (1.0, 3)
    
        8
  •  0
  •   Amara BOUDIB    7 年前

    最复杂的是在一个列表中替换,我认为:

            import numpy as np
    
            l = [2., None, 3., 1., None, 2., None, 5.]
    
            #### function to replace in a list 
            def replaced(sequence, old, new):
                return (new if x == old else x for x in sequence)
    
            l=list(replaced(l,None,np.nan))
    
            #### numpy specific function
            position = np.nanargmin(l)
            value = l[position]
    
            print(position, value)
    
        9
  •  -1
  •   ergesto    7 年前

    为什么结果应该是(1,3),1,2之后是

    l = [2., None, 3., 1., None, 2., None, 5.]
    
    bar = map(float, [e for e in l if isinstance(e, float)])
    print (min(float(i) for i in bar))