Как удалить определенные подстроки из набора строк в Python?

161

У меня есть набор строк set1, и все строки set1имеют две конкретные подстроки, которые мне не нужны, и я хочу удалить.
Пример ввода: set1={'Apple.good','Orange.good','Pear.bad','Pear.good','Banana.bad','Potato.bad'}
Поэтому в основном я хочу, чтобы .goodи .badподстроки удалены из всех строк.
Что я пробовал:

for x in set1:
    x.replace('.good','')
    x.replace('.bad','')

Но это, похоже, не работает вообще. В выводе нет абсолютно никаких изменений, и он совпадает с вводом. Я попытался использовать for x in list(set1)вместо оригинального, но это ничего не меняет.

ControlFreak
источник

Ответы:

188

Строки неизменны. string.replace(python 2.x) или str.replace(python 3.x) создает новую строку. Об этом говорится в документации:

Вернуть копию строки s, в которой все вхождения подстроки old заменены на new. ...

Это означает, что вы должны перераспределить набор или заново заполнить его (перераспределение легче с пониманием набора) :

new_set = {x.replace('.good', '').replace('.bad', '') for x in set1}
Реут Шарабани
источник
3
string.replace()устарела на python 3.x, теперь этоstr.replace()
Yossarian42
71
>>> x = 'Pear.good'
>>> y = x.replace('.good','')
>>> y
'Pear'
>>> x
'Pear.good'

.replaceне изменяет строку, она возвращает копию строки с заменой. Вы не можете изменить строку напрямую, потому что строки неизменны.

Вам нужно взять возвращаемые значения x.replaceи поместить их в новый набор.

Алекс Холл
источник
Но когда я перебираю набор строк, как я могу обновить новый набор? используя set_name.update? Не могли бы вы показать это?
controlfreak
12

Все, что вам нужно, это немного черной магии!

>>> a = ["cherry.bad","pear.good", "apple.good"]
>>> a = list(map(lambda x: x.replace('.good','').replace('.bad',''),a))
>>> a
['cherry', 'pear', 'apple']
gueeest
источник
5

Вы могли бы сделать это:

import re
import string
set1={'Apple.good','Orange.good','Pear.bad','Pear.good','Banana.bad','Potato.bad'}

for x in set1:
    x.replace('.good',' ')
    x.replace('.bad',' ')
    x = re.sub('\.good$', '', x)
    x = re.sub('\.bad$', '', x)
    print(x)
Вивек
источник
2
линия x.replace('.good',' ')и x.replace('.bad',' ')не делает ничего для конечного результата. Распечатка будет такой же без них.
Срджан Попич
Кроме того, я предпочел бы иметь только одну линию re.sub, как это:x = re.sub('((\.good$)|(\.bad$))', '', x)
Срджан Popić
@ SrđanPopić да, я согласен с тобой
Вивек
мы должны отредактировать это соответственно? (удалить replaces и переместить все на один re.subзвонок)
Срджан Popić
1
@ SrđanPopić Я публикую этот ответ, потому что он прост и шаг за шагом.
Вивек
3

Я сделал тест (но это не ваш пример), и данные не возвращают их упорядоченно или полностью

>>> ind = ['p5','p1','p8','p4','p2','p8']
>>> newind = {x.replace('p','') for x in ind}
>>> newind
{'1', '2', '8', '5', '4'}

Я доказал, что это работает:

>>> ind = ['p5','p1','p8','p4','p2','p8']
>>> newind = [x.replace('p','') for x in ind]
>>> newind
['5', '1', '8', '4', '2', '8']

или

>>> newind = []
>>> ind = ['p5','p1','p8','p4','p2','p8']
>>> for x in ind:
...     newind.append(x.replace('p',''))
>>> newind
['5', '1', '8', '4', '2', '8']
user140259
источник
3

Когда нужно удалить несколько подстрок, одним простым и эффективным вариантом является использование re.subскомпилированного шаблона, который включает в себя объединение всех подстрок, которые необходимо удалить, с помощью канала regex OR ( |).

import re

to_remove = ['.good', '.bad']
strings = ['Apple.good','Orange.good','Pear.bad']

p = re.compile('|'.join(map(re.escape, to_remove))) # escape to handle metachars
[p.sub('', s) for s in strings]
# ['Apple', 'Orange', 'Pear']
cs95
источник
1

Если список

Я делал что-то для списка, который представляет собой набор строк, и вы хотите удалить все строки, которые имеют определенную подстроку, вы можете сделать это

import re
def RemoveInList(sub,LinSplitUnOr):
    indices = [i for i, x in enumerate(LinSplitUnOr) if re.search(sub, x)]
    A = [i for j, i in enumerate(LinSplitUnOr) if j not in indices]
    return A

где subскороговорка, которую вы не хотите иметь в списке строкLinSplitUnOr

например

A=['Apple.good','Orange.good','Pear.bad','Pear.good','Banana.bad','Potato.bad']
sub = 'good'
A=RemoveInList(sub,A)

Тогда Aбудет

введите описание изображения здесь

rsc05
источник
0

если вы удалите что-то из списка, вы можете использовать этот способ: (метод sub чувствителен к регистру)

new_list = []
old_list= ["ABCDEFG","HKLMNOP","QRSTUV"]

for data in old_list:
     new_list.append(re.sub("AB|M|TV", " ", data))

print(new_list) // output : [' CDEFG', 'HKL NOP', 'QRSTUV']
mamal
источник