2016-04-27 37 views
0

所以我遇到了一些麻煩,試圖調試這段代碼。我有一個數字列表,例如[4,5,7,3,5,2,3],我需要找到兩個最接近的點,所以在這種情況下,3和3因爲它們的差值爲零。但是,它不會返回正確的輸出。如果一個數字不在列表中重複出現,但它在某個數字出現多次時不起作用。點列表並找到最近的點故障

def closest1(num_list): 
     if len(num_list) < 2: 
      return (None, None) 
     else: 
      diff = max(num_list), min(num_list) 
      for element in num_list: 
       for sec_element in num_list: 
        if sec_element == element: 
         continue 
        if abs(sec_element - element) < abs(diff[0] - diff[1]): 
         diff = sec_element, element 
     return diff 
+0

你試過列表進行排序,第一 – Keatinge

+0

'[X在num_list x如果num_list.count(X)> 1]'將返回重複。如果沒有,您可以繼續對列表進行排序並找出差異。 – jDo

+0

還有另一對距離爲0(5,5)的列表。有沒有一種方法可以選擇(3,3)或者沒關係? – sal

回答

0

我認爲你的問題是,當你找到相同的數字,你運行一個continue語句。在那個地方,條件應該是每個數字的位置。如果位置相同,則應該跳過該數字,但如果位置不同並且數字相同則是有效的情況。

在另一方面,您不需要查找既不是最小值也不需要查找最大值,然後計算最長距離。從前兩個數字的差異開始,以獲得更好的表現。

下面是代碼的固定:

def closest1(num_list): 
     if len(num_list) < 2: 
      return (None, None) 
     else: 
      num1 = num_list[0] 
      num2 = num_list[1] 
      diff = abs(num1 - num2) 
      if diff == 0: # Better case ever! You compute almost nothing! :D 
       return num1, num2 
      # enumerates(list) gives you the pair (position, value) for each item of the list. 
      for p1, element in enumerate(num_list): 
       for p2, sec_element in enumerate(num_list): 
        if p1 == p2: # Compare positions, not values ;) 
         continue # Here is the big fix! 
        if abs(sec_element - element) < abs(diff): 
         diff = sec_element - element 
         num1 = element 
         num2 = sec_element 
         if diff == 0: # Great case! Don't have to compute all the list! :) 
          return num1, num2 
     return num1, num2 

if __name__ == '__main__': 
    print("Should be 0,1 and it is %s,%s" % closest1(range(10))) 
    print("Should be 4,4 and it is %s,%s" % closest1([4,5,6,7,8,6,4,2])) 

您可以直接運行它。

注意:此代碼僅用於教育目的,有更多高性能的方法。

0

您可以使用itertools首先提供列表中所有元素的組合,然後計算它們的distance。最後一步是隻返回該名單的min,所以你的功能可能會被改寫爲:

import itertools 
def closest1(num_list): 
    return min([(abs(x[0]-x[1]),x) for x in itertools.combinations(num_list, 2)]) 

返回(0,(3,3)) 見這裏的行動:https://eval.in/560204

0

也許那就是你想要的?

如果你想要最接近的數字,我認爲這是解決方案。

如果你想要最小差異返回差異。

def closest(num_list): 
    tmp = (None, None) 
    diff = max(num_list) - min(num_list) 
    for i in range(len(num_list)): 
     for j in range(len(num_list)): 
      if i != j and diff >= abs(num_list[i] - num_list[j]) : 
       tmp = (num_list[i], num_list[j]) 
       diff = abs(num_list[i] - num_list[j]) 
    return tmp 
print(closest([4,5,7,3,5,2,3])) 
0

只有一個循環是必要的,如果您排序第一:

def closest1(num_list): 
    num_list = sorted(num_list) 
    diff = num_list[0] - num_list[-1] 
    diff_dict = {"num1":diff, "num2":diff, "diff":diff} 
    for pos, val in enumerate(num_list[:-1]): 
     diff = abs(num_list[pos+1] - val) 
     if diff < diff_dict["diff"]: 
      diff_dict = {"num1":num_list[pos+1], "num2":val, "diff":diff} 
    return diff_dict 
+0

是的,我們應該使用嵌套for循環這個功能...第二個功能使用排序 – PythonSOS

+0

@PythonSOS好吧,我忘記這些問題有時是功課。嵌套循環經常在真實代碼中避免,但如果這是必需的,我認爲Svaris或Hamlett的解決方案是迄今爲止最好的。 – jDo

0

必須使用range迭代這樣的條件if sec_element == element:不會混淆拖的比較與相同的值不同的元素元素與自身的比較。

此外,您不必遍歷第二個循環中的所有元素。這裏是你的代碼的變化:

def closest1(num_list): 
    if len(num_list) < 2: 
     return (None, None) 

    a, b = num_list[0], num_list[1] 
    diff = b - a 
    for i in range(len(num_list)): 
     for j in range(i): 
      new_diff = num_list[i] - num_list[j] 
      if abs(new_diff) < abs(diff): 
       diff = new_diff 
       a, b = num_list[i], num_list[j] 
    return a, b