Як видалити конкретні підрядки з набору рядків у Python?


160

У мене є набір рядків 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)замість оригіналу, але це нічого не змінило.

Відповіді:


187

Струни незмінні. string.replace(python 2.x) або str.replace(python 3.x) створює новий рядок. Про це йдеться в документації:

Повернути копію рядка s зі всіма входженнями старої підрядки, заміненої на нову. ...

Це означає, що вам доведеться перерозподілити набір або повторно заповнити його (повторне виділення простіше за допомогою розуміння набору) :

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? Чи можете ви це показати?
контролер

12

Все, що вам потрібно, це трохи чорної магії!

>>> a = ["cherry.bad","pear.good", "apple.good"]
>>> a = list(map(lambda x: x.replace('.good','').replace('.bad',''),a))
>>> a
['cherry', 'pear', 'apple']

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',' ')нічого не робить до кінцевого результату. Друк буде однаковий без них.
Srđan Popić

Також я хотів би мати лише один рядок re.sub, як-от так:x = re.sub('((\.good$)|(\.bad$))', '', x)
Srđan Popić

@ SrđanPopić так, я згоден з вами
Vivek

чи слід це редагувати відповідно? (видаліть replaces та перенесіть все на один re.subдзвінок)
Srđan 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']

3

Коли є кілька підрядків для видалення, одним простим та ефективним варіантом є використання re.subзі складеним шаблоном, який передбачає приєднання всіх підрядків для видалення за допомогою регекс-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']

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буде

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


0

якщо ви видалите щось зі списку, ви можете скористатися таким чином:

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']
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.