Проблема со списком Python

#python #list #search #indexing #return

#python #Список #Поиск #индексирование #Возврат

Вопрос:

Мне нужны некоторые подсказки или пример, как я могу локализовать список в списке a b , а затем заменить его списком c .

 a=[1,3,6,2,6,7,3,4,5,6,6,7,8]
 

введите b список (это подсписок, который программа ищет в списке a ).

 b=[6,7]
 

при обнаружении возвращайте мне индексы, в которых был найден подсписок, и заменяйте его каждый раз на c=[0,0] , так что результат будет

 [1,3,6,2,0,0,3,4,5,6,0,0,8]
 

Ответ №1:

Вот более эффективный подход, чем мой первый, с использованием нарезки списков:

 >>> for i in xrange(len(a) - len(b)   1):
...     if a[i:i len(b)] == b:
...         a[i:i len(b)] = c
... 
>>> a
[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8]
 

Первая попытка, для потомков….

Если вам не нужны промежуточные индексы, вот один из подходов, использующий строковые функции и применяющий функциональный подход, не изменяя ваш список на месте.

 >>> a_as_str = ','.join(str(i) for i in a)
>>> print a_as_str
1,3,6,2,6,7,3,4,5,6,6,7,8
>>> b_as_str = ','.join(str(i) for i in b)
>>> b_as_str
'6,7'
>>> c_as_str = ','.join(str(i) for i in c)
>>> c_as_str
'0,0'
>>> replaced = a_as_str.replace(b_as_str, c_as_str)
>>> replaced
'1,3,6,2,0,0,3,4,5,6,0,0,8'
>>> [int(i) for i in replaced.split(',')]
[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8]
 

Это может быть переработано как:

 >>> def as_str(l):
...     return ','.join(str(i) for i in l)
... 
>>> def as_list_of_ints(s):
...     return [int(i) for i in s.split(',')]
... 
>>> as_list_of_ints(as_str(a).replace(as_str(b), as_str(c)))
[1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8]
 

Комментарии:

1. Преобразование из целых чисел в строки и обратно для меня гораздо менее понятно, чем прямой поиск по списку. Также это приводит к значительному снижению производительности (хотя в данном случае это может быть неуместно).

2. Это очень удобно и эффективно, но здесь есть одна проблема: замена выполняется на месте, в то время как размер шага потенциально (вероятно) меньше размера замены. Это немного сложно обойти, поскольку, по-видимому, вы хотели бы, чтобы произошла первая допустимая замена.

3. @amicitas: Спасибо. Я не уверен, что это проблема, поскольку замена [0, 0] и поиск [6, 7] не пересекаются.

Ответ №2:

вы можете сделать что-то похожее на (написано на python 3.2, используется xrange в python 2.x):

 for i in range(0, len(a)):
    if a[i:i len(b)] == b:
        a[i:i len(b)] = c
 

это будет учитывать списки всех размеров.
Это предполагает list b == list c , что я не знаю, хотите ли вы этого, однако, пожалуйста, укажите, если это не так.

Вывод для списков:

 a = [1,2,3,4,5,6,7,8,9,0]
b = [1,2]
c = [0,0]
Output:
[0, 0, 3, 4, 5, 6, 7, 8, 9, 0]
 

Комментарии:

1. о, вау, я даже не видел список b, я отредактирую ответ. РЕДАКТИРОВАТЬ: и готово

2. Для заданных значений a, b, c , указанных в вопросе, это теперь возвращается a как [1, 3, 0, 0, 0, 0, 3, 4, 5, 6, 0, 0, 8]

3. Спасибо за это, при исправлении ошибки выравнивания, которую я вызвал, цикл for тестировал только первое значение, и теперь я получаю решение, которое вы опубликовали = d

4. Это исправлено! Я знаю это, потому что теперь он такой же, как у меня, за исключением того, что вы перебираете еще один индекс.

Ответ №3:

Я привожу вам пример

 li=[1,3,6,2,6,7,3,4,5,6,6,7,8]
for i  in range(len(li)): 
    if li[i:i   2] == [3, 4]: 
        li[i:i   2] = [0, 0]
 

Я думаю, что этот код должен работать. Если вам нужен более надежный скрипт, я предлагаю вам проверить вхождения подстроки в исходном списке и отредактировать копию (чтобы избежать поведения побочных эффектов).

Комментарии:

1. Некоторые улучшения: используя имена переменных, используемые op, вы можете сделать диапазон похожим range(len(a) - len(b)) на; if if a[i:i len(b)] == b ; присваивание a[i:i len(b)] = c .

Ответ №4:

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

Я думаю, что эта функция должна обрабатывать все случаи по назначению:

 def replace(a, b, c):
    ii = 0
    while ii <= (len(a) - len(b)   1):
        print(ii)
        if a[ii:ii len(b)] == b:
            a[ii:ii len(b)] = c
            ii  = len(b)
        else:
            ii  = 1
    return a
 

Вывод с использованием исходного примера:

 [1, 3, 6, 2, 0, 0, 3, 4, 5, 6, 0, 0, 8]
 

Вот пример, в котором подстановка создает шаблон поиска:

 a = [1,1,1,1,1,1,1,1,1,6,6,7,7,1]
b = [6,7]
c = [0,6]
 

Вывод, как и ожидалось:

 [1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 0, 6, 7, 1]
 

Есть идеи о том, как сделать это немного более кратко?