Нахождение точной позиции меньшего списка внутри списка (python) - PullRequest
2 голосов
/ 27 октября 2011

Итак, у меня есть список, похожий на этот:

list=[10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 10.0, 9.9, 10.0, 10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 9.9, 9.9, 9.9, 10.0, 10.0, 10.0, 10.2, 10.0, 9.9, 9.9, 9.9, 9.9, 10.0, 10.2, 10.0, 9.9, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.1, 10.0, 10.0, 10.0, 10.0, 10.0, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.3, 10.3, 10.2, 10.2, 10.3, 10.3, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.3, 10.2, 10.5, 10.9, 10.5, 10.3, 10.3, 10.3, 10.2, 10.2, 10.2, 10.2, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.4, 10.7, 10.3, 10.2, 10.1, 10.1, 10.0, 10.0, 10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 10.0, 9.9, 9.9, 9.9, 10.1, 9.9, 9.9, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.7, 9.8, 9.8, 9.7, 9.7, 9.7, 9.7, 9.7, 9.7, 9.6, 9.7]

И еще у меня есть подсписок, который выглядит примерно так:

sublist=[9.9, 9.9, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8]

Теперь, что мне нужно сделать с этим меньшим списком, так это то, что мне нужно найти, где это находится в основном списке. Таким образом, в этом случае результат должен выглядеть примерно так: index = 119 (я могу отключить +/- 1)

Я пытался сделать это весь день ... И ничего не нашел в сети ... У меня есть несколько идей:

1) Я нахожу первый элемент подсписка в списке .... который в этом случае будет равен 4, поэтому я проверяю следующий номер, который также является правильным, затем следующий, который будет неправильным, и он отправит найти другой 9.9 в оставшемся списке [4:] и повторить тот же цикл ... пока не будет найдено точное соответствие

2) Тогда другая идея состоит в том, чтобы как-то использовать строки str (list) [1: -1] .find (str (sublist) [1: -1]), который в этом случае даст ответ 687 ...

Проблема с этими идеями в том, что они кажутся длинными и неряшливыми, а также я не смог заставить эти идеи работать ...

Ответы [ 4 ]

3 голосов
/ 27 октября 2011

Как насчет:

l = [10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 10.0, 9.9, 10.0, 10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 9.9, 9.9, 9.9, 10.0, 10.0, 10.0, 10.2, 10.0, 9.9, 9.9, 9.9, 9.9, 10.0, 10.2, 10.0, 9.9, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.1, 10.0, 10.0, 10.0, 10.0, 10.0, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.3, 10.3, 10.2, 10.2, 10.3, 10.3, 10.2, 10.2, 10.2, 10.2, 10.2, 10.2, 10.3, 10.2, 10.5, 10.9, 10.5, 10.3, 10.3, 10.3, 10.2, 10.2, 10.2, 10.2, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.1, 10.4, 10.7, 10.3, 10.2, 10.1, 10.1, 10.0, 10.0, 10.0, 10.0, 10.0, 9.9, 9.9, 9.9, 10.0, 9.9, 9.9, 9.9, 10.1, 9.9, 9.9, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.7, 9.8, 9.8, 9.7, 9.7, 9.7, 9.7, 9.7, 9.7, 9.6, 9.7]
subl = [9.9, 9.9, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8, 9.8]
for i in xrange(len(l)-len(subl)):
  if l[i:i+len(subl)] == subl:
    print 'found at pos', i
    break
else:
  print 'not found'

Это печатает found at pos 118.

P.S. Я переименовал переменные, чтобы list не скрывал встроенную функцию.

2 голосов
/ 28 октября 2011
ind = l.index(subl[0])
for i in xrange(l.count(subl[0])-1):
    if l[ind:ind+len(subl)] == subl:
        print (ind)
        break;
    ind = l.index(subl[0],ind+1)

Это эффективный способ, который сравнивает только тогда, когда ему известно хотя бы первое значение subl.

1 голос
/ 28 октября 2011
idx = next(i for i in range(len(lst)-len(sublst)) if lst[i:i+len(sublist)] == sublst)
# 118
1 голос
/ 27 октября 2011

Ваша вторая идея может дать ложный положительный результат: если бы подсписок имел одно значение, скажем, 1, а полный список имел только значение 11, он нашел бы совпадение. Если вы добавили в свою строку начальные и конечные разделители, этого можно избежать.

Ваша первая идея на полпути к оптимальному решению; Существует алгоритм (имя которого ускользает от меня на данный момент) для определения того, какую часть подстроки вы можете «повторно использовать», так что вам никогда не придется возвращаться назад в полной строке. Например, предположим, что ваш текущий кандидат провалился, потому что вы нашли 9,9, где вы ожидали 9,8; Вам не нужно повторно посещать этот элемент, потому что он соответствует первому элементу подстроки. Они могут быть предварительно вычислены, так что вы в конечном итоге просто пройдете весь список за один проход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...