Comment supprimer des sous-chaînes spécifiques d'un ensemble de chaînes en Python?

161

J'ai un ensemble de chaînes set1et toutes les chaînes dans set1ont deux sous-chaînes spécifiques dont je n'ai pas besoin et que je veux supprimer.
Exemple d'entrée: set1={'Apple.good','Orange.good','Pear.bad','Pear.good','Banana.bad','Potato.bad'}
Donc, fondamentalement, je veux que les sous .good- .badchaînes et soient supprimées de toutes les chaînes.
Ce que j'ai essayé:

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

Mais cela ne semble pas du tout fonctionner. Il n'y a absolument aucun changement dans la sortie et c'est la même chose que l'entrée. J'ai essayé d'utiliser à la for x in list(set1)place de l'original mais cela ne change rien.

controlfreak
la source

Réponses:

188

Les chaînes sont immuables. string.replace(python 2.x) ou str.replace(python 3.x) crée une nouvelle chaîne. Ceci est indiqué dans la documentation:

Renvoie une copie de la chaîne s avec toutes les occurrences de la sous-chaîne old remplacées par new. ...

Cela signifie que vous devez réallouer l'ensemble ou le remplir à nouveau (la réallocation est plus facile avec la compréhension de l'ensemble) :

new_set = {x.replace('.good', '').replace('.bad', '') for x in set1}
Reut Sharabani
la source
3
string.replace()est obsolète sur python 3.x, maintenant il l'eststr.replace()
Yossarian42
71
>>> x = 'Pear.good'
>>> y = x.replace('.good','')
>>> y
'Pear'
>>> x
'Pear.good'

.replacene change pas la chaîne, il retourne une copie de la chaîne avec le remplacement. Vous ne pouvez pas modifier la chaîne directement car les chaînes sont immuables.

Vous devez extraire les valeurs de retour x.replaceet les placer dans un nouvel ensemble.

Alex Hall
la source
Mais lorsque je boucle sur l'ensemble de chaînes, comment puis-je mettre à jour un nouvel ensemble? en utilisant set_name.update? Pouvez-vous montrer cela?
controlfreak
12

Tout ce dont vous avez besoin est un peu de magie noire!

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

Vous pouvez faire ceci:

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)
Vivek
la source
2
ligne x.replace('.good',' ')et x.replace('.bad',' ')ne fait rien au résultat final. L'impression sera la même sans eux.
Srđan Popić
Aussi, je préfère avoir juste une ligne avec re.sub, comme ceci:x = re.sub('((\.good$)|(\.bad$))', '', x)
Srđan Popić
@ SrđanPopić ouais je suis d'accord avec vous
Vivek
devrions-nous le modifier en conséquence? (supprimer replaces et tout déplacer en un seul re.subappel)
Srđan Popić
1
@ SrđanPopić Je poste cette réponse car elle est simple et pas à pas.
Vivek
3

J'ai fait le test (mais ce n'est pas votre exemple) et les données ne les renvoient ni ordonnées ni complètes

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

J'ai prouvé que cela fonctionne:

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

ou

>>> 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
la source
3

Lorsqu'il y a plusieurs sous-chaînes à supprimer, une option simple et efficace consiste à utiliser re.subavec un modèle compilé qui implique de joindre toutes les sous-chaînes à supprimer à l'aide du |tube 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
la source
1

Si liste

Je faisais quelque chose pour une liste qui est un ensemble de chaînes et vous voulez supprimer toutes les lignes qui ont une certaine sous-chaîne, vous pouvez le faire

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

subest un motif que vous ne souhaitez pas avoir dans une liste de lignesLinSplitUnOr

par exemple

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

Alors Asera

entrez la description de l'image ici

rsc05
la source
0

si vous supprimez quelque chose de la liste, vous pouvez utiliser cette méthode: (la méthode sub est sensible à la casse)

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
la source