在列表中找到最接近数字的代码时遇到问题

时间:2018-05-01 17:52:53

标签: python python-3.x

我正在制作一些代码,允许我从列表中选择最接近的数字,我已设法做到这一点。但是,当找到最接近的号码并且其号码超过“我的号码”时我希望python在它之前打印出列表中的数字。

例如;

如果我有一个清单;

TwoN = [1,2,4,8,16,32,64,128,256,512, 1024, 2048, 4096, 8192]

myNumber = 30

我希望python打印16而不是32

这是我到目前为止所做的代码......

TwoN = []
for i in range(12):
    TwoN.append(2**i)
print(TwoN)

myNumber = 30
closest = TwoN[0]
for i in range(1, len(TwoN)):
    if abs(TwoN[i] - myNumber) < abs(closest - myNumber):
        closest = TwoN[i];


Sum = myNumber - closest
if Sum < 0:
    closest = TwoN[(i-1)]
    print(closest)
else:
    print(closest)

当myNumber = 30时,程序将输出1024,我希望它输出16 ..

感谢任何帮助

3 个答案:

答案 0 :(得分:5)

您可以使用带条件的简单列表推导来过滤掉更大的数字并返回其余数字的最大值:

TwoN = [1,2,4,8,16,32,64,128,256,512, 1024, 2048, 4096, 8192]

def closestLowerNr(data,num):
    """returns from data the biggest number smaller/equal to num""" 
    return max( nr for nr in data if nr <= num) # get max of nr that are smaller/equal

print(closestLowerNr(TwoN,38)) 

if nr <= number丢弃任何大于所需数字的内容,max( ... )会为您提供剩余的最大数字。

你也可以只传递一次你的清单,并获得低于你的最高数字以及高于你的数字:

TwoN = []
for i in range(12):
    TwoN.append(2**i)
print(TwoN)

myNumber = 32

belowMine = None
aboveMine = None

                     # this is almost always preferable to a range(len(list)) loop                
for nr in TwoN:      # if you really need an index use for i,v in enumerate(list): 
    if not belowMine or nr > belowMine: # get lower bound closest to myNumber
        if nr < myNumber:
            belowMine = nr 
    if not aboveMine or nr < aboveMine: # get upper bound closest to myNumber
        if nr > myNumber:
            aboveMine = nr 

    if nr == myNumber: # exact match, we are done
        belowMine = nr
        aboveMine = nr
        break

if nr == myNumber:       
    print ("Found:",nr)
else:
    print ("Closest numbers to ",myNumber," found:", belowMine,aboveMine)

输出:

[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]
Found: 32
# or 
Closest numbers to  30  found: 16 32

答案 1 :(得分:3)

您可以使用bisect模块:

import bisect

TwoN = [1,2,4,8,16,32,64,128,256,512, 1024, 2048, 4096, 8192]
myNumber = 30

print(TwoN[bisect.bisect(TwoN, myNumber) - 1])
# 16

bisect.bisect会在列表值的右侧返回myNumber的插入点,之后必须插入该插入点以使其保持有序。因此,我们只需要减去1来获得列表中最大值的索引,该索引小于或等于myNumber

答案 2 :(得分:3)

正如@abarnert所说,如果它已经分类,很容易找到

for i in TwoN:
    if i < 30:
        seen = i
    else:
        print seen
        break

>16