Почему при попытке разбить строку по повторяющимся буквам/символам, итерация проходит не по всей строке?

Делю следующей функцией строку ('1111aa994bbbb1111AAAAAFF?<mmM!!!!!!!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzzzzzxxxxxxxxaaaaaaaaaaaaaaaaaaaaaaaaabf')

по повторяющимся символам:

def find_longest_substr(s):
    for i, k in enumerate(s):
        if s[i] != s[i+1] and not s[i].isspace():
            s = s[:i+1] + ' ' + s[i+1:]
    return s

print(find_longest_substr('1111aa994bbbb1111AAAAAFF?<mmM!!!!!!!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzzzzzxxxxxxxxaaaaaaaaaaaaaaaaaaaaaaaaabf'))

Получаю ответ: 1111 aa 99 4 bbbb 1111 AAAAA FF ? < mm M !!!!!!! aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa zzzzzz xxxxxxxx aaaaaaaaaaaaaaaaaaaaaaaaabf

Ожидал получить: 1111 aa 99 4 bbbb 1111 AAAAA FF ? < mm M !!!!!!! aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa zzzzzz xxxxxxxx aaaaaaaaaaaaaaaaaaaaaaaaa b f

то есть, в конце символы тоже должны быть разделены пробелами. Вопрос следующий: почему в конце группа из букв "а", а также b и f не отделены друг от друга пробелами?


Ответы (3 шт):

Автор решения: Amgarak

Как вам уже ответили в комментариях, не нужно менять итерируемый объект это может вызвать кучу проблем.

def find_longest_substr(string):
    result = ""
    for i, char in enumerate(string[:-1]):
        if char != string[i+1] and not char.isspace():
            result += char + ' '
        else:
            result += char
    return result + string[-1]# если последний симвл не повторяется, то тоже его добавим 

s = '1111aaи994bbbb1111AAAAAFF?<mmM!!!!!!!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzzzzzxxxxxxxxaaaaaaaaaaaaaaaaaaaaaaaaabf'
print(find_longest_substr(s))

Вывод:

1111 aa и 99 4 bbbb 1111 AAAAA FF ? < mm M !!!!!!! aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa zzzzzz xxxxxxxx aaaaaaaaaaaaaaaaaaaaaaaaa b f

[Program finished]
→ Ссылка
Автор решения: чистов_n - за Россию

Никогда не изменяйте список который вы итерируете!

Я переписал ваш код так:

def find_longest_substr(s):
    result = ''

    if not s: return  # Если нам передали пустую строку, завершаем.

    symbol = s[0]

    for i in s:
        if i != symbol:  # Если тек. символ не равен пред. символ, добавляем пробел.
            result += ' '
            symbol = i
        result += symbol

    return result


print(find_longest_substr('1111aa994bbbb1111AAAAAFF?<mmM!!!!!!!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzzzzzxxxxxxxxaaaaaaaaaaaaaaaaaaaaaaaaabf'))

Вывод:

11111 aa 99 4 bbbb 1111 AAAAA FF ? < mm M !!!!!!! aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa zzzzzz xxxxxxxx aaaaaaaaaaaaaaaaaaaaaaaaa b f
→ Ссылка
Автор решения: Алексей Р

Можно воспользоваться функцией groupby() из модуля itertools.

from itertools import groupby


def find_longest_substr(s):
    return ' '.join(''.join(g) for _, g in groupby(s))


print(find_longest_substr('1111aa994bbbb1111AAAAAFF?<mmM!!!!!!!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzzzzzxxxxxxxxaaaaaaaaaaaaaaaaaaaaaaaaabf'))
1111 aa 99 4 bbbb 1111 AAAAA FF ? < mm M !!!!!!! aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa zzzzzz xxxxxxxx aaaaaaaaaaaaaaaaaaaaaaaaa b f
→ Ссылка