2015-06-05 31 views
2

我有一個包含大量子列表的列表。即Python,比較子列表和製作列表

mylst = [[1, 343, 407, 433, 27], 
     [1, 344, 413, 744, 302], 
     [1, 344, 500, 600, 100], 
     [1, 344, 752, 1114, 363], 
     [1, 345, 755, 922, 168], 
     [2, 345, 188, 1093, 906], 
     [2, 346, 4, 950, 947], 
     [2, 346, 953, 995, 43], 
     [3, 346, 967, 1084, 118], 
     [3, 347, 4, 951, 948], 
     [3, 347, 1053, 1086, 34], 
     [3, 349, 1049, 1125, 77], 
     [3, 349, 1004, 1124, 120], 
     [3, 350, 185, 986, 802], 
     [3, 352, 1018, 1055, 38]] 

我想開始先分類列表和使用三個步驟使另一個列表。首先,當每個子列表中的第一項相同時,我想比較子列表,即mylist [a] [0] == 1。其次,比較子列表中的第二項,如果子列表中的第二項與另一個第二項之間的差異小於2,則計算第三項或第四項之間的差異。如果第三和第四項中的任何一項差異小於10,那麼我想追加子列表的索引。

,我想應該是......這樣的結果是:[0, 1, 3, 4, 6, 7, 10, 11, 12]

以下是我天真的嘗試做到這一點。

以下是我天真的嘗試做到這一點。

def seg(mylist) : 
    Segments = [] 
    for a in range(len(mylist)-1) : 
     for index, value in enumerate (mylist) : 
      if mylist[a][0] == 1 : 
       if abs(mylist[a][1] - mylist[a+1][1]) <= 2 : 
        if (abs(mylist[a][2] - mylist[a+1][2]) <= 10 or 
         abs(mylist[a][3] - mylist[a+1][3]) <= 10) : 
         Segments.append(index) 
return Segments 

def seg(mylist) : 
    Segments= [] 
    for index, value in enumerate(mylist) : 
     for a in range(len(mylist)-1) : 
      if mylist[a][0] == 1 : 
       try : 
        if abs(mylist[a][1]-mylist[a+1][1]) <= 2 : 
         if (abs(mylist[a][2]-mylist[a+1][2]) <= 10 or 
          abs(mylist[a][3] - mylist[a+1][3]) <= 10) : 
          Segments.append(index) 
       except IndexError : 
        if abs(mylist[a][1]-mylist[a+1][1]) <= 2 : 
         if (abs(mylist[a][2]-mylist[a+1][2]) <= 10 or 
          abs(mylist[a][3] - mylist[a+1][3]) <= 10): 
          Segments.append(index) 
return Segments 

這些代碼並不好看的一切,結果沒有顯示爲我打算。在底部,我寫了try和除了處理索引錯誤(列表超出範圍),最初我使用'while'迭代而不是'for'迭代。

我該怎麼做才能獲得我想要的結果?我如何糾正這些代碼看起來更像'pythonic'的方式? 任何想法對我來說都很棒,很多事先感謝。

+2

你們爲什麼把那些不必要的'其他:pass'線?如果沒有它們,你的代碼將更加令人愉快。你應該打破這些冗長的界限,用括號來做到這一點。他們可以很容易地破壞'或'陳述。 –

+2

只要對第二次嘗試發表評論,在try和except語句中具有* exact *相同的事物通常是問題的標誌。 – shuttle87

+0

忘記了刪除其他內容並通過了句子,我實際上正在研究它並且只是粘貼了這個。謝謝你的評論。 – winterfield

回答

1

你必須趕上重複的索引,但這個應該是很多更高效:

gr = [] 
it = iter(mylst) 
prev = next(it) 

for ind, ele in enumerate(it): 
    if ele[0] == prev[0] and abs(ele[1] - prev[1]) <= 2: 
     if any(abs(ele[i] - prev[i]) < 10 for i in (2, 3)): 
      gr.extend((ind, ind+1)) 
    prev = ele 

根據您的邏輯6,7不應該出現,因爲他們不符合標準:

 [2, 346, 953, 995, 43], 
    [3, 346, 967, 1084, 118], 

也爲10出現應該是<= 2沒有< 2根據您的描述。

你可以使用一個OrderedDict刪除受騙者,並保持順序:

from collections import OrderedDict 

print(OrderedDict.fromkeys(gr).keys()) 
[0, 1, 3, 4, 10, 11, 12] 
+0

真棒,它的作品!非常感謝...只是哇,只是幾行陳述.. – winterfield

+0

不用擔心,就像我說的一些索引將被添加兩次,所以你需要處理 –

0

這似乎爲我工作。我不確定它是否會以任何方式使用更多的Pythonic,並且您將多次循環訪問列表,因此您可以通過某些方法來優化它。

def seg(mylist): 
    # converted list to set in case there are any duplicates 
    segments = set() 

    for entry_index in range(len(mylist)): 
     for c in range(len(mylist)): 
      first = mylist[entry_index] 
      comparison = mylist[c] 

      # ignore comparing the same items 
      if entry_index == c: 
       continue 

      # ignore cases where the first item does not match 
      if first[0] != comparison[0]: 
       continue 

      # ignore cases where the second item differs by more than 2 
      if abs(first[1] - comparison[1]) > 2: 
       continue 

      # add cases where the third and fourth items differ by less than 10 
      if abs(first[2] - comparison[2]) < 10 or abs(first[3] - comparison[3]) < 10: 
       segments.add(entry_index) 

      elif abs(first[2] - comparison[3]) < 10 or abs(first[3] - comparison[2]) < 10: 
       segments.add(entry_index) 

    return segments 
+0

非常感謝,這也適用! – winterfield