查找最小元素及其在列表中的位置与 Nones



我有一个数字列表,None是这样的:

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

我想获取最小数字及其索引,而Nones 应该被简单地忽略。对于给定的示例,结果将是:

(1., 3)

当然,编写一个做我想做的事情的函数很简单,但我更喜欢一些有效的内置或至少是高级方法。 我对Python 3的解决方案特别感兴趣,其中min函数不接受None作为参数。

min((v,i) for i,v in enumerate(l) if v is not None)
(1.0, 3) # (value, index)

我可能会分成两部分:

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()并使用带有lambdaenumerate()返回来检查i[1]索引中的值(例如2.0, inf, ..., 5.0(。因此,最终元组仅使用原始列表中的生成器"过滤和替换"NoneType索引,只需一次迭代即可返回。

您可以定义一个转换函数并将其与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
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

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

如果这是一个问题,可以包括一个检查值不是 inf(即 l 中没有数字的情况(

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

这是一种方法。

演示:

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)

您可以避免使用这样的key

>>> import operator as op
>>> import itertools as it
>>> min(it.filterfalse(op.methodcaller('__contains__', None), zip(l, it.count())))
(1.0, 3)

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

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)

虽然我更喜欢接受的答案。 可以使用NoneType的演示代码:

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


def converter(x):
NoneType = type(None)
return x[1] if not isinstance(x[1], NoneType) else float('inf')


res = min(enumerate(lst), key=converter)[::-1]
print(res)

(1.0, 3)

为什么结果应该是(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))

最新更新