Изменение списка, который вы повторяете, похоже на распиливание ветви, на которой вы сидите. Python повторяет список по индексам. По индексу 0 вы удаляете 0-й элемент ("h"
). Теперь "i"
является 0-м элементом, но у Python не будет другой итерации с индексом 0, он переходит к индексу 1 на следующей итерации, а "i"
никогда не рассматривается.
Лучший способсделать это, в частности, используя re.sub
:
re.sub(r'[^()]', '', 'hi(hi)()')
Если вы хотите более общее решение, тогда фильтрование элементов лучше выполнить с помощью функции filter
, или эквивалентно и более Python, с условным пониманием:
''.join(c for c in 'hi(hi)()' if c == '(' or c == ')')
Если вам нужно использовать цикл и удалять элементы, то выполните цикл в обратном порядке. Это как сидеть на другой стороне пилы, на стороне, которая не падает. Когда вы удаляете элемент, вы не изменяете индекс какого-либо элемента, который вам еще предстоит перебрать.
РЕДАКТИРОВАТЬ: И, как вы поняли из комментария, гораздо проще просто создать новую структуру данных, что полностью исключает проблему изменения структуры, по которой вы выполняете итерацию. Это именно то, что делают и приведенные выше решения для регулярных выражений и понимания.