2014-09-02 2 views
-1

Я ввел следующий код для удаления гласных, но он не работает специально для повторяющихся букв! просто запустите мой код, чтобы понять проблему!метод удаления в списке Python не удаляет повторяющиеся буквы

def anti_vowel(text): 

    text=list(text) 

    for i in text: 

     if i=='e' or i=='E' or i=='a' or i=='O' or i=='o' or \ 

     i=='A' or i=='u' or i=='U' or i=='i' or i=='I': 

     text.remove(i) 

text1=''.join(text) 

text2=str(text1) 

return text 

print anti_vowel("Hey Look World!") 

Я искал интернет и найти ответ, чтобы изменить мой код:

for i in text[:]: 

сказать мне, что происходит?

+2

я не могу запустить его, потому что отступы инвалид. – vaultah

+0

В чем смысл 'text1' и' text2', когда все, что вы делаете, возвращает 'text'? –

+0

Альтернатива: 'return re.sub (r '[aeiou]', '', text, flags = re.IGNORECASE)'. – Matthias

ответ

2

Как документация ясно говорит, list.remove будет:

удалить первое вхождение значения

Так, конечно, он не удаляет все вхождения значения. Это похоже на то, что функция, называемая print, печатает значения вместо их умножения на 3.

Если вы хотите удалить все вхождения значения, вы можете это сделать. Например, вы можете вызвать remove в цикле, пока он не поднял ValueError.


Но с вашим кодом гораздо большие проблемы.

Во-первых, вы не можете удалять вещи из списка, итерации по нему. Это вызовет все виды плохих вещей - чаще всего это приведет к тому, что итерация пропустит многие значения. Вы часто можете решить эту проблему, повторив ее назад, но это не сработает, если вы используете такие функции, как remove, которые по своей сути работают с фронта. Вы почти всегда можете решить эту проблему, перебирая копию списка (это то, что делает ваш for i in text[:]:; text[:] - это копия фрагмента всего списка).

Во-вторых, вы дублируете свою работу. Зачем вручную искать каждый 'e' только для звонка remove, чтобы он мог искать с начала по первому e? Либо избавитесь от внешнего цикла и просто позвоните remove, пока вы не закончите, или не избавитесь от remove и просто используйте del, чтобы удалить значение, которое вы уже сделали, тяжелую работу по поиску или, самое главное, реорганизовать ваш код, чтобы вы могли просто сделать все в порядке.

Так, три с половиной варианта:


for vowel in 'AEIOUaeiou': 
    while True: 
     try: 
      text.remove(vowel) 
     except ValueError: 
      break 

for i, letter in reversed(enumerate(text)): 
    if letter in 'AEIOUaeiou': 
     del text[i] 

for i, letter in enumerate(text[:]): 
    if letter in 'AEIOUaeiou': 
     del text[i] 

text = [letter for letter in text if letter not in 'AEIOUaeiou'] 

Или, как указывает Маттиас, регулярное выражение может быть лучшим ответом в этом случае; Единственная проблема заключается в том, что вы должны преобразовать список в строку, чтобы запустить re.sub на него, а затем преобразовать его обратно в список после этого ... но это очень просто:

text = list(re.sub(r'[aeiou]', '', ''.join(text), flags=re.IGNORECASE))