如何从值最接近零的列表中查找两个索引

时间:2013-08-23 14:47:46

标签: python python-2.7

我正在为我的GA工作(实际上是适应度计算),我需要从列表中得到两个值的索引,其值最接近于零。我一直在互联网上寻找大约一个小时,虽然看起来我变得非常接近,看起来它应该有效,用print语句测试表明我的代码不起作用..

我现在的流程是:

  1. 查找最近的索引并存储
  2. 从原始数组中删除
  3. 找到新的最近的
  4. 这是有问题的代码:

    closest = min(range(len(fitness_levels)), key=lambda i: abs(fitness_levels[i]-0))
    fitness_levels.pop(closest)
    second_closest = min(range(len(fitness_levels)), key=lambda i: abs(fitness_levels[i]-0))
    

    授予fitness_levels = [-20, 23, -55, 11, 10, -18, -48, 16, -60, 20, 22, 16, 21, 66, 10, 46, -42]时,这些数字是完全随机生成的。

    就像我说的那样,当我用print语句进行一些检查时,我发现这种方法可以通过多种方式运行,有一点我甚至得到了相同的索引不同的值。有没有人有更好的可行方法来做到这一点? - python 2.7.x

    旁注 - 我来自php背景,仍然热身到python,所以一些语法可能是错误的......

4 个答案:

答案 0 :(得分:3)

虽然使用abs键进行排序可行,但这是一个nlogn解决方案。这是一个线性解决方案

fitness_levels = [-20, 23, -55, 11, 10, -18, -48, 16, -60, 20, 22, 16, 21, 66, 10, 46, -42]
a,b = sorted(fitness_levels[:2], key=abs) # setting defaults. a<=b
ia, ib = 0,1 # indices
for i,val in enumerate(fitness_levels[2:]): # use itertools.islice for large lists (for constant space)
  if abs(val) < abs(a):
    b,a = a,val
    ib, ia = ia, i
  elif abs(val) < abs(b):
    b = val
    ib = i

答案 1 :(得分:0)

这样的事情:

>>> lis = [-20, 23, -55, 11, 10, -18, -48, 16, -60, 20, 22, 16, 21, 66, 10, 46, -42]
for i,x in enumerate(sorted(enumerate(lis), key=lambda x:abs(0 - x[1]))[:2]):
    x = list(x)
    x[0] -= i    #reduce index as an item was removed from the list
    ind, val = x
    print "{}->{}".format(ind, val)
...     
4->10
13->10

如果你不想减少索引,那么这就足够了:

>>> sorted(enumerate(lis), key=lambda x:abs(0-x[1]))[:2]
[(4, 10), (14, 10)]

答案 2 :(得分:0)

我会去:

fitness_levels = [-20, 23, -55, 11, 10, -18, -48, 16, -60, 20, 22, 16, 21, 66, 10, 46, -42]

import heapq
closest2 = heapq.nsmallest(2, ((abs(val), idx) for idx, val in enumerate(fitness_levels)))
# [(10, 4), (10, 14)]
indices = [el[1] for el in closest2]
# [4, 14]

答案 3 :(得分:0)

怎么样:

>>> from numpy import argsort,abs
>>> fitness_levels = [-20,23,-55,11,10,-18,-48,16,-60,20,22,16,21,66,10,46,-42]
>>> i,j = argsort(abs(fitness_levels))[:2]
>>> print (i,fitness_levels[i]),(j,fitness_levels[j])
>>> (14 10) (4 10)