考虑像[0,3,7,10,12,15,19,21]
这样的列表,我想得到最接近任何值的最接近的最小数字,所以如果我通过4
,我会得到3
,如果我通过{ {1}},我会得到18
等等。
答案 0 :(得分:3)
您可以使用bisect并不太难。它用于这样的二进制搜索。这确实假定了一个排序列表。
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)
运行互动:
>>> 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
答案 1 :(得分:0)
这里有几个选择。
最简单的是迭代数组并在a)你到达数组末尾时停止或b)当前位置的值大于你要查找的值。然后只需返回找到的最后一个值。 (需要考虑的一个优势:如果请求的数量小于数组的所有值,会发生什么?)
此解决方案假定数组已订购。如果没有,它将无法工作。
答案 2 :(得分:0)
如果您的列表很小,那么迭代它是最好的选择。你可以避免一些开销,加上过度设计这项任务毫无意义。如果您希望您的代码更“正确”,或者您希望在较大的输入上进行良好的扩展,我建议使用二进制搜索方法。当然,这是假设您的输入保证被排序。如果未排序,除了在跟踪delta之前迭代值,您别无选择。以下是二元搜索策略的相对高级别的解释:
通过一些示例来向自己证明这将起作用可能会有所帮助。
答案 3 :(得分:0)
您可以使用yield
和next()
来避免迭代整个列表
在线演示 - 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
答案 4 :(得分: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]
答案 5 :(得分: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。)我们不能假设原件是预先分类的,因为它没有这样指定。因此,我做了一个就地排序。如果需要保留列表项的顺序,则复制列表然后排序。
(2。)有一些使用bisect模块和使用迭代器的优秀帖子。我想通过演示列表推导以及使用抛弃变量(下划线)来展示另一种方式。
(3。)如果列表很长,你应该使用bisect。如果列表很短(指定不超过几百),请不要过度设计代码;线性搜索很好。请记住,在软件中,你总是在兼顾,时间与空间,可读性,可维护性等等。
答案 6 :(得分:0)
使用bisect。
一个问题:一旦检查号码小于列表中的第一个元素
import bisect
lst = [0, 3, 7, 10, 12, 15, 19, 21]
lst[bisect.bisect_left(lst,-1) - 1]
答案 7 :(得分:-2)
好吧, $('form').on('submit',function(e){
e.preventDefault()
// TODO
console.log('Form is submitted to the server');
});
$("#Color").change(function () {
$(this).find("option:selected").each(function(){
var val = $(this).attr("value");
var box = $(".box");
if(val=="redd"){
box.not("." + val).hide().find("input").removeAttr('required');
$("." + val).show().find("input").prop("required", true);
}
else if(val=="greenn"){
box.not("." + val).hide().find("input").removeAttr('required');
$("." + val).show().find("input").prop("required", true);
}
else{
$(".box").hide();
}
});
}).change();
是列表,a
是值:
b
更有效的方式?可能不是吗?