#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))
на; ifif 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]
Есть идеи о том, как сделать это немного более кратко?