2016-07-06 52 views
3

考虑像[0,3,7,10,12,15,19,21]名单,我想最近获得最近的最低位为任意值,所以如果我通过4,我会得到3,如果我通过18,我会得到15蟒蛇食谱:最近等于列表项看重

+1

第一要素就越小名单总是排序?当你说*“最接近的最小值”*你是指最大的数字小于输入,还是三角洲实际上很重要? – jonrsharpe

+1

如果该值等于列表中的条目,该怎么办?我们应该去下一个最大的还是返回相同的数字? –

+0

基于他的例子,我会说我们不确定它是否被排序(可能不是因为他的回答没有排序)。我也会说,根据他的回答,他正在寻找平等的比赛。 – woot

回答

-2

好,a是列表和b值:

max(a for a in a if a <= b) 

更有效的方式?可能不会?

+1

它当然不会给出正确的答案。 – jonrsharpe

+1

@marcusshep那没有什么区别 – jonrsharpe

+0

max,当然是最小,修正了它。 – Wells

0

这里有几个选项。

最简单的方法是迭代数组,并在以下情况停止:a)到达数组的末尾或b)当前位置的值大于要查找的值。然后简单地返回找到的最后一个值。 (需要考虑的一种边界情况:如果请求的数量小于阵列的所有数值,会发生什么情况?)

此解决方案假定数组是有序的。如果不是,它将不起作用。

0

如果您的清单很小,通过它迭代是最好的选择。你会避免一些开销,并且没有必要过度设计这个任务。如果你希望你的代码更加“正确”,或者如果你想在更大的输入上进行扩展,我推荐使用二分搜索方法。当然,这是假设您的输入被保证被排序。如果未排序,除了在追踪增量的同时遍历数值之外别无选择。这里的二进制搜索战略的一个相对高的水平解释:

  1. 做一个二进制搜索
  2. 如果等于你正在寻找的价值,以前的索引返回值。
  3. 如果小于该值,则返回该索引。
  4. 如果大于该值,则返回上一个索引。

这可能有助于通过几个例子来证明自己这会起作用。

0

您可以使用yieldnext()避免遍历整个列表

在线演示 - https://repl.it/C9YJ/1

values = [0,3,7,10,12,15,19,21] 

def get_closest(value, items): 

    previews_item = None 
    for item in items: 
     if item >= value: 
      yield previews_item 

     previews_item = max(item, previews_item) if previews_item else item 

    yield None 


print next(get_closest(4, values)) 
# 3 

print next(get_closest(18, values)) 
# 15 
0

真的很乱,可能低效的解决方案,但它的工作原理

test=[0,3,7,10,12,15,19,21] 
value=25 
nearest=[] 
for i in test: 
    if i == value: 
     nearest.append(test[(test.index(i))]) 
     break 
    if i>value: 
     nearest.append(test[(test.index(i))-1]) 
     break 
if len(nearest) == 0: 
    nearest.append(test[-1]) 

print nearest[0] 
3

你可以使用bisect这不是太di fficult。它用于这样的二进制搜索。这确实假定了一个排序列表。

from bisect import bisect_right 

def find_le(a, x): 
    'Find rightmost value less than or equal to x' 
    i = bisect_right(a, x) 
    if i: 
     return a[i-1] 
    raise ValueError 

mylist = [0,3,7,10,12,15,19,21] 
print find_le(mylist,4) 
print find_le(mylist,-1) 
print find_le(mylist,29) 
print find_le(mylist,12) 

运行Interactive:

>>> print find_le(mylist,4) 
3 
>>> print find_le(mylist,-1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 6, in find_le 
ValueError 
>>> print find_le(mylist,29) 
21 
>>> print find_le(mylist,12) 
12 
0
x = [0,3,7,10,12,15,19,21] 
val = 18 

x.sort() 
close = [abs(_ - val) for _ in x] 
ans = (x[close.index(min(close))]) 
if ans > val: 
    ans = (x[close.index(min(close)) -1]) 
print (ans) 

评论:

(1)我们cannnot假设原来是预先排序,因为它没有被指定为此类。因此,我做了一个就地排序。如果需要保留列表项目的顺序,请复制列表并进行排序。

(2.)有一些优秀的职位使用平分模块,并使用迭代器。我想通过展示列表解析和使用抛出变量(下划线)来展示另一种方式。

(3.)如果列表很长,则应该使用bisect。如果列表很短(指定不超过几百个),请勿过度设计代码;线性搜索很好。只要记住在软件中,你总是在玩耍,时间与空间,可读性,可维护性等等。

+0

虽然这段代码可能回答这个问题,但提供关于为什么和/或代码如何回答这个问题的附加上下文会提高它的长期价值。 – Ajean

+0

感谢您的反馈,Ajean!我将评论我自己的代码,希望我能够增加一些价值。 – Joe

0

使用二分法。
一个问题:代码将为最后一个元素一次检查数量比列表

import bisect 
lst = [0, 3, 7, 10, 12, 15, 19, 21] 
lst[bisect.bisect_left(lst,-1) - 1]