2016-07-06 54 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]