我的Python有点生疏,我真的遇到了这个超级简单算法的问题。
我正在尝试编写一个函数,它接受两个参数(目标,值)来查找值中哪个数字最接近目标数字;如果碰巧有平局,那么选择较低的数字。
这是我的进步,但是我只选择了较低的数字而没有实际比较列表中的值与目标的相对距离的差异。
所以,从本质上讲,我的功能根本没有完全正确地完成挑战,因为47实际上接近46而不是31;但是,如果列表中包含的数字假设为45和47,则它们与我的目标数量相等,因此应该打印45而不是47。
我更喜欢使用简单的/ if / while循环的答案,这样我才能真正练习我的技能。
其他更高级的答案也欢迎详细说明。
修改
你们的一些非常好的答案,非常感谢;我正在测试它们,并且会选择最符合我风格的那个,并使用其余的作为参考,即使你有最佳的单行答案。
target = 46
values = [1, 22, 31, 47, 87, 99]
def closest_to_target(target, values):
lower = []
for number in values:
if number < target:
lower.append(number)
if lower:
lowest = sorted(lower, reverse=True)[0]
return lowest
else:
return "Error handling array"
print closest_to_target(target, values)
答案 0 :(得分:4)
您只选择小于目标的数字,无论区别如何。对于您请求的基本代码示例,您需要考虑对线性搜索进行修改,但只需跟踪最低差异和产生此最小差异的值。
def closest(target, values):
smallest_difference = #a really large value to start
closest_number = None
for number in values:
diff = abs(number - target)
if diff == smallest_difference and number < closest_number:
closest_number = number
if diff < smallest_difference:
closest_number = number
smallest_difference = diff
return closest_number
此方法的优点是您不会创建其他列表。
答案 1 :(得分:3)
您可以使用以下函数创建值的元组,以及该值与目标值的接近程度。通过这个元组排序,您不仅可以获得最接近目标值的元素,而且在关系的情况下,将选择最小的并列值。
target = 46
values = [1, 22, 31, 47, 87, 99]
def closest_min(l, t):
return sorted([(abs(t-i), l[e]) for e, i in enumerate(l)])[0][1]
print(closest_min(values, target))
输出:
47
在平局的情况下,将正确选择最低:
>>> closest_min([47, 45], 46)
45
使用min()
的稍微整洁的版本:
def closest_min(l, t):
return min(l, key=lambda x:(abs(x-t), x))
答案 2 :(得分:3)
这可以在一次通过中完成,跟踪增量。如果delta等于前一个delta,则最接近的是前一个最近和当前的min。如果delta较小,则使用当前值更新delta和最接近的delta。还有别的,继续前进。
>>> target = 46
>>> values = [1, 22, 31, 47, 87, 99]
>>> closest = values[0]
>>> delta = abs(target - closest)
>>> for x in values:
... d = abs(target - x)
... if d == delta:
... closest = min(closest, x)
... elif d < delta:
... delta = d
... closest = x
...
>>> delta
1
>>> closest
47
>>>
答案 3 :(得分:1)
def min_dist_index(target, values):
values = sorted(values)
dists = [abs(target-value) for value in values]
index = dists.index(min(dists))
return values[index]
target = 46
values = [1, 22, 31, 47, 87, 99]
print(min_dist_index(target, values))
输出:47
答案 4 :(得分:-1)
您可以生成一个有效数字列表,然后可以使用所谓的列表推导进行处理:
values[[abs(target-i) for i in values].index(min([abs(target-i) for i in values]))]
这里列表文字[]用于定义通用算法,而不是列表内容应该是特定值。列表中的每个元素i都是从包含您的值的列表文字派生的,并根据目标编号进行检查。如果他们没有资格,则他们不包含在新生成的列表中。
实现:
#!/usr/bin/env python
target = 46
values = [1, 22, 31, 47, 87, 99]
def closest_to_target(target, values):
lower = values[[abs(46-i) for i in values].index(min([abs(46-i) for i in values]))]
return lower
print(closest_to_target(target, values))
将打印:
47