Python 如何找到序列中与参数最接近的两个值?
我想写一个代码,不使用任何模块就可以找到与给定参数最接近的两个数字。下面是我目前的情况Python 如何找到序列中与参数最接近的两个值?,python,python-3.x,list,Python,Python 3.x,List,我想写一个代码,不使用任何模块就可以找到与给定参数最接近的两个数字。下面是我目前的情况 list1 = (1,3,5,8,12) x = 9 for value in list1: point = list1[x - 1], list1[x + 1] 预期输出为[8,12]您可以使用排序的平方距离列表来实现它。通过计算差并求平方,可以消除负距离。接近目标值的事物,即 9 - x = 0 ==> squared 0 10 -
list1 = (1,3,5,8,12)
x = 9
for value in list1:
point = list1[x - 1], list1[x + 1]
预期输出为
[8,12]
您可以使用排序的平方距离列表来实现它。通过计算差并求平方,可以消除负距离。接近目标值的事物,即
9 - x = 0 ==> squared 0
10 - x = 1 ==> squared 1
8 - x = -1 ==> squared 1
12 - x = 3 ==> squared 9 etc.
离得近一点,事情离得远一点
# your "list" was a tuple - make it a list
data = [1,3,5,8,12]
x = 9
# calculate the difference between each value and your target value x
diffs = [t-x for t in data]
print(diffs)
# sort all diffs by the squared difference
diffsSorted = sorted([t-x for t in data], key = lambda x:x**2)
print(diffsSorted)
# take the lowes 2 of them
diffVals = diffsSorted[0:2]
print(diffVals)
# add x on top again
values = [t + x for t in diffVals]
print(values)
# Harder to understand, but you could reduce it into a oneliner:
allInOne=[k+x for k in sorted([t-x for t in data], key = lambda x:x**2)][:2]
print(allInOne)
输出:
[-8, -6, -4, -1, 3] # difference between x and each number in data
# [64, 36, 16, 1, 9] are the squared distances
[-1, 3, -4, -6, -8] # sorted differences
[-1, 3] # first 2 - just add x back
[8, 12] # result by stepwise
[8, 12] # result allInOne
中间步骤(未打印):
比较heapq和list方法的一些测量值(改为abs(),而不是平方): 输出:
# rnd-size list approch heapq
{
10: ( 0.06346651086960813, 0.11704596144812314),
100: ( 0.5278085906813885, 0.8281634763797711),
1000: ( 5.032436315978541, 7.462741343986483),
10000: ( 54.45165343575938, 79.96112521267483),
100000: (577.708372381287, 835.539905495399)
}
列表总是比heapq快,heapq(尤其是对于较大的列表)在空间共变性方面要好得多。您可以使用排序的平方距离列表来实现它。通过计算差并求平方,可以消除负距离。接近目标值的事物,即
9 - x = 0 ==> squared 0
10 - x = 1 ==> squared 1
8 - x = -1 ==> squared 1
12 - x = 3 ==> squared 9 etc.
离得近一点,事情离得远一点
# your "list" was a tuple - make it a list
data = [1,3,5,8,12]
x = 9
# calculate the difference between each value and your target value x
diffs = [t-x for t in data]
print(diffs)
# sort all diffs by the squared difference
diffsSorted = sorted([t-x for t in data], key = lambda x:x**2)
print(diffsSorted)
# take the lowes 2 of them
diffVals = diffsSorted[0:2]
print(diffVals)
# add x on top again
values = [t + x for t in diffVals]
print(values)
# Harder to understand, but you could reduce it into a oneliner:
allInOne=[k+x for k in sorted([t-x for t in data], key = lambda x:x**2)][:2]
print(allInOne)
输出:
[-8, -6, -4, -1, 3] # difference between x and each number in data
# [64, 36, 16, 1, 9] are the squared distances
[-1, 3, -4, -6, -8] # sorted differences
[-1, 3] # first 2 - just add x back
[8, 12] # result by stepwise
[8, 12] # result allInOne
中间步骤(未打印):
比较heapq和list方法的一些测量值(改为abs(),而不是平方): 输出:
# rnd-size list approch heapq
{
10: ( 0.06346651086960813, 0.11704596144812314),
100: ( 0.5278085906813885, 0.8281634763797711),
1000: ( 5.032436315978541, 7.462741343986483),
10000: ( 54.45165343575938, 79.96112521267483),
100000: (577.708372381287, 835.539905495399)
}
列表总是比heapq快,heapq(尤其是对于较大的列表)在空间共变性方面要好得多。尝试以下方法:
t= [abs(i-x) for i in list1]
sorted_list = sorted(enumerate(t), key=lambda i:i[1])
(list1[sorted_list[0][0]], (list1[sorted_list[1][0]]))
它返回所需值的元组(8,12)
尝试以下操作:
t= [abs(i-x) for i in list1]
sorted_list = sorted(enumerate(t), key=lambda i:i[1])
(list1[sorted_list[0][0]], (list1[sorted_list[1][0]]))
它返回所需值的元组
(8,12)
请为您的问题加上您的预期输出添加一个最小且可验证的示例。请为您的问题加上您的预期输出添加一个最小且可验证的示例。在这里使用heapq似乎是一个理想的情况,特别是考虑到两个最接近的匹配,例如:heapq.nsmallest(2,数据,lambda L:abs(9-L))
-这样,您在任何时候都只保留两个最接近的值,并且只应用一次键,而不必在装饰后对整个序列进行排序。(哦,恭喜你跑了10公里!)速度(速度慢)和空间(使用更少)之间有一个折衷。。。所以,虽然它不一定明显更好,但它可能是一个值得注意的选项。@JonClements将x**2更改为abs(x)是一个我没有想到的好方法。我在timeit上运行了一些大小的数据-heapq的速度慢了大约50%-但是对于大列表,只记住5个值而不是100k是非常大的-所以感谢您的评论和gratsJust注意到。。。您的key=lambda x:abs(x)
具有您不需要的呼叫级别。。。您可以在那里使用key=abs
。。。可能不是世界上最庞大的加速,但有一个不必要的开销减少了:)似乎是使用heapq的理想情况,特别是考虑到两个最接近的匹配,例如:heapq.nsmallest(2,数据,lambda L:abs(9-L))
-这样,您在任何时候都只保留最接近的两个键,只应用一次键,而不必在装饰后对整个序列进行排序。(哦,恭喜你跑了10公里!)速度(速度慢)和空间(使用更少)之间有一个折衷。。。所以,虽然它不一定明显更好,但它可能是一个值得注意的选项。@JonClements将x**2更改为abs(x)是一个我没有想到的好方法。我在timeit上运行了一些大小的数据-heapq的速度慢了大约50%-但是对于大列表,只记住5个值而不是100k是非常大的-所以感谢您的评论和gratsJust注意到。。。您的key=lambda x:abs(x)
具有您不需要的呼叫级别。。。您可以在那里使用key=abs
。。。可能不是世界上最庞大的加速,但少了一个不必要的开销:)abs()而不是(i-x)**2。。。nice+1abs()而不是(i-x)**2。。。尼斯+1