2015-06-05 3 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' итерацию.

Что мне делать, чтобы получить результат, который я хотел? Как я могу исправить эти коды, чтобы они выглядели более «путинским» способом? Любая идея была бы большой для меня, и большое спасибо заранее.

+2

Почему вы держите эту ненужную 'еще: pass' линию? Ваш код будет намного приятнее читать без них. И вы должны сломать эти длинные строки, используя скобки для этого. Их можно легко сломать вокруг операторов 'или'. –

+2

Просто комментарий о второй попытке, имеющий * точный * то же самое в 'try' и' except', как правило, является признаком проблемы. – 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

Смежные вопросы