почему эта функция python пропускает индекс от 1 до 3 без итерации индекса 2 при запуске в цикле for

#python #python-3.x #for-loop

#python #python-3.x #for-цикл

Вопрос:

Я написал функцию для удаления частей, которые дублируются в двух строках. Сначала я преобразую строку в список и перебираю два списка, чтобы найти, совпадают ли символы в одной и той же позиции. Проблема в том, что при итерации код пропускает индекс 2. (например: list =»index», итератор переходит к ‘d’ после итерации ‘i’).

Я пытался использовать метод «replace» для выполнения строковой операции, но я не получил желаемого результата. Метод «Replace» удалил нужные мне части.

 def popp(s,t): 
    s_lis=list(s)
    t_lis=list(t)
    ind=0
    for i,j in zip(s_lis,t_lis):
        if i==j:
            s_lis.pop(ind)
            t_lis.pop(ind)
        else:ind =1        
    return s_lis,t_lis

# test the code
print(popp('hackerhappy','hackerrank'))
  
 expected result: ['h','p','p','y'] ['r','n','k']
actual result: ['k', 'r', 'h', 'a', 'p', 'p', 'y'], ['k', 'r', 'r', 'a', 'n', 'k']
  

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

1. Для достижения этой цели вы можете использовать zip_longest . Проверьте мой ответ ниже

Ответ №1:

Для начала вам следует использовать itertools.zip_longest, который создает zip из самой длинной подпоследовательности. Вы используете zip , который создает zip-файл из кратчайшей подпоследовательности, чего вы не хотите.
Итак, в нашем случае это будет

 print(list(zip_longest(s_lis, t_lis)))
#[('h', 'h'), ('a', 'a'), ('c', 'c'), ('k', 'k'), ('e', 'e'), 
#('r', 'r'), ('h', 'r'), ('a', 'a'), ('p', 'n'), ('p', 'k'), ('y', None)]
  

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

 from itertools import zip_longest
def popp(s,t):
    s_lis = list(s)
    t_lis = list(t)
    s_res = []
    t_res = []
    #Use zip_longest to zip the two lists
    for i, j in zip_longest(s_lis, t_lis):
        #If the characters do not match, and they are not None, append them 
        #to the list
        if i != j:
            if i!=None:
                s_res.append(i)
            if j!=None:
                t_res.append(j)
    return s_res, t_res
  

Результат будет выглядеть так:

 print(popp('hackerhappy','hackerrank'))
#(['h', 'p', 'p', 'y'], ['r', 'n', 'k'])
  

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

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

2. Да, вы никогда не должны изменять список с помощью pop, как вы делали, и уже выполняли итерацию.

Ответ №2:

Вы могли бы немного изменить свой код

 def popp(s, t):
    s_lis = list(s)
    t_lis = list(t)
    s_res = []
    t_res = []

    # match each character. Stops once the
    # shortest list ends
    for i, j in zip(s_lis, t_lis):
        if i != j:
            s_res.append(i)
            t_res.append(j)

    # if s is longer, take rest of the string and
    # add it to residual
    if len(s) > len(t):
        for x in s_lis[len(t):]:
            s_res.append(x)

    if len(t) > len(s):
        for x in t_lis[len(s):]:
            t_res.append(x)

    print(s_res)
    print(t_res)

popp('hackerhappy','hackerrank')