Как использовать встроенный цикл for для замены подстрок?

#python #formatting

#python #форматирование

Вопрос:

Я пытаюсь заменить подстроки ни на что. Например, я хочу преобразовать £1,000.90 в 1000.90 , т.е. просто заменить '£' и ‘ ,' ничем. И я подумал, что сделаю это с помощью встроенного for цикла.

 s = '£1,000.90'
replaceStrings = ['£', ',']
s = (s.replace(x, '') for x in replaceStrings)
print(s)
 

Но это не работает.
Я нахожу много альтернатив для этого, но я подумал, что попробую использовать встроенный for цикл.

Редактировать: ответы интересны. Каков самый простой способ замены списка символов на что-то другое. Тот же пример, упомянутый ниже. У меня есть список replaceStrings . Они должны быть удалены / заменены на пустые / x из исходной строки s .

 s = '£1,000.90'
replaceStrings = ['£', ',']
 

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

1. Вы не можете сделать это с помощью итератора. Это возвращает отдельный результат для каждого элемента replaceStrings , но не объединяет их. Используйте обычный цикл.

2. Используйте re.sub() , если вы хотите заменить несколько строк одним и тем же.

3. Добро пожаловать в SO! Обратите внимание, что в Python «встроенный цикл for» называется выражением генератора ( python.org/dev/peps/pep-0289 ).

4. @Barmar Я бы сказал, что это рабочее решение с итератором: *_, s = ((s := s.replace(x, '')) for x in replaceStrings)

5. @superbrain Можете ли вы дать более подробное объяснение этой строки? Он включает в себя множество функций, которые я еще не изучил.

Ответ №1:

(s.replace(x, '') for x in replaceStrings) создает генератор, который выдает версии s со строками из replaceStrings удаленных. Очевидно, что это не то, чего вы хотите.

Это прекрасный пример того, когда регулярное выражение было бы хорошим вариантом:

 import re

s = '£1,000.90'
s = re.sub('£|,', '', s)
print(s)
 

Ответ №2:

Вы также могли бы использовать translate .

 >>> s.translate(dict.fromkeys(map(ord, replaceStrings)))
'1000.90'
 

Или если replaceStrings бы была строка ( '£,' ):

 >>> s.translate(str.maketrans('', '', replaceStrings))
'1000.90'
 

Но лучшим вариантом может быть цикл:

 for c in replaceStrings:
    s = s.replace(c, '')
 

Кстати, replaceStrings кажется, плохое название для «списка символов«, который вы хотите удалить. Кроме того, список символов — это строковая вещь в Python. Тогда можно просто использовать строку.

Ответ №3:

 "".join([i for i in s if i not in(",","£")])
 

Надеюсь, это ответит на ваш вопрос

Ответ №4:

Используйте re.sub так:

 import re
s = '£1,000,000.90'
s = re.sub(r'[£,]', '', s)
print(s)
# 1000000.90
 

Ответ №5:

Используемый вами синтаксис создает генератор, который при повторной итерации будет выполнять замены. Но тогда замена не влияет s .

Комментарий, предлагающий использовать обычный for цикл, верен. Вы можете написать это в одной строке, если настаиваете:

 for x in replaceStrings: s = s.replace(x, '')
 

Если вы действительно хотите злоупотреблять выражением генератора и используете Python 3.8 или более поздней версии, где поддерживается оператор walrus := , вы также можете сделать это следующим образом:

 all((s := s.replace(x, '')) for x in replaceStrings)
 

Вот all встроенная функция, которая возвращает True , являются ли все элементы в итеративном объекте истинными. Он завершает работу и возвращается False , если видит ложный элемент. У этого есть небольшое преимущество в том, что он остановится, если s когда-либо станет пустым, что будет означать, что все остальные операции замены не нужны. Обычно, однако, такого рода дурачества были бы запахом кода, и ваш вариант использования не нуждается в таком поведении.

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

1. Они приберегают все запасные s части .

2. Нет, они хранят генератор s . Они никогда не повторяют его, поэтому ни одна из замен не выполняется.