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.

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}

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.


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']

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)

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']

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']

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


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']
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.