2014-05-08 83 views
0

我有Python中的數字列表。它看起來像這樣:在Python列表中查找彼此相距一定距離內的數字

a = [87, 84, 86, 89, 90, 2014, 1000, 1002, 997, 999] 

我想保留所有相互在+或 - 7之內的數字,並放棄其餘的。有沒有簡單的方法來在Python中做到這一點?我已閱讀關於列表過濾器方法,但不知道如何得到我想要的工作。

我是Python新手。

更新

輸出理想地[84,86,87,89,90]和另一個列表[997,999,1000,1002]。我想檢索序列而不是異常值。希望這是有道理的。

+2

什麼是上面所列的烏爾預期輸出 –

+0

輸出理想地[84,86,87,89,90]和另一個列表[997,999,1000,1002] – user1022788

+0

請更新您的問題與預期的輸出。這個列表的大小是否最小?如果沒有'[2014]'也是一個解決方案。 – reto

回答

1

這是算法的問題,試試這個:

def get_blocks(values): 
    mi, ma = 0, 0 
    result = [] 
    temp = [] 
    for v in sorted(values): 
     if not temp: 
      mi = ma = v 
      temp.append(v) 
     else: 
      if abs(v - mi) < 7 and abs(v - ma) < 7: 
       temp.append(v) 
       if v < mi: 
        mi = v 
       elif v > ma: 
        ma = v 
      else: 
       if len(temp) > 1: 
        result.append(temp) 
       mi = ma = v 
       temp = [v] 
    return result 

a = [87, 84, 86, 89, 90, 2014, 1000, 1002, 997, 999] 
print get_blocks(a) 

輸出:

[[84, 86, 87, 89, 90], [997, 999, 1000, 1002]] 
1

如果你的問題,允許傳遞關係,即x是該組中,只要它是在最多7遠離任何元素在組中,那麼這在我看來就像一個graph theory問題。更具體地說,你需要找到所有的connected components

問題本身很容易用遞歸算法解決。你首先要創建一個字典,其中每個鍵都是元素之一,每個值都是一個元素列表,最多與該元素相距7。對於你的榜樣,你有這樣的事情:

for element in elements: 
    connections[element] = [] 
    visited[element] = False 
    for another in elements: 
     if abs(element - another) <= limit: 
      connections[element].append(another) 

這將使你這樣的事情

{ 
    84: [86, 87, 89, 90], 
    86: [84, 87, 89, 90], 
    ... 
    997: [999, 1000, 1002] 
    ... 
    2014: [] 
} 

現在你需要編寫一個遞歸函數,將作爲輸入的元素與列表,只要它能夠找到一個與當前元素相距最多7的元素,就會在列表中添加元素。

def group_elements(element, group): 
    if visited[element]: 
     return 
    visited[element] = True 
    group.append(element) 
    for another in connections[element]: 
     group_elements(another, group) 

某處在代碼也需要記住您已經訪問過,以確保你不進入一個無限循環的元素。

visited = {} 

您需要爲列表中的每個元素調用該函數。

groups = [] 
for element in elements: 
    if not visited[element]: 
     group = [] 
     group_elements(element, group) 
     groups.append(group) 
print group 

此代碼應該給下面的輸出你的投入:

[[87, 84, 86, 89, 90], [2014], [1000, 1002, 997, 999]] 
0
a = [87, 84, 86, 89, 90, 2014, 1000, 1002, 997, 999] 
temp=a[0] 
result=[] 
temp1=[] 
counter =len(a) 

for i in a: 
    if i in range(temp-7,temp+7): 


     temp1.append(i) 
     if counter==1: 
      result.append(temp1) 

    else: 


     if temp1: 
      result.append(sorted(temp1)) 
     temp1=[] 
     temp=i 
    counter=counter-1 

print result 
0

對於這樣我的第一個停靠港的任何問題是Python itertools module成對功能從我在代碼中使用的鏈接可在more-itertools module

from more_itertools import pairwise 
results = [] 
chunk = [] 
a = [87, 84, 86, 89, 90, 2014, 1000, 1002, 997, 999] 
a.sort() 
for v1, v2 in pairwise(a): 
    if v2 - v1 <= 7: 
     chunk.append(v1) 
    elif chunk: 
     chunk.append(v1) 
     results.append(chunk) 
     chunk = [] 
print(results) 
[[84, 86, 87, 89, 90], [997, 999, 1000, 1002]] 

我沒有測試對邊緣情況,所以它的買方小心:)