Suppression de caractères spécifiques d'une chaîne de caractères en Python

J&#8217essaie de supprimer des caractères spécifiques d&#8217une chaîne de caractères en utilisant Python. Voici le code que j'utilise actuellement. Malheureusement, il ne semble rien faire à la chaîne.

for char in line:
    if char in " ?.!/;:":
        line.replace(char,'')

Comment faire correctement ?

Solution

Les chaînes de caractères en Python sont immuables (ne peuvent pas être modifiées). Pour cette raison, l'effet de line.replace(...) est juste de créer une nouvelle chaîne, plutôt que de changer l'ancienne. Vous devez rebinder (assigner) la variable à line pour qu'elle prenne la nouvelle valeur, avec les caractères supprimés.

De plus, la façon dont vous le faites va être relativement lente. Elle risque également d'être un peu déroutante pour les pythoniciens expérimentés, qui verront une structure doublement imbriquée et penseront un instant que quelque chose de plus compliqué se passe.

À partir de Python 2.6 et des versions plus récentes de Python 2.x *, vous pouvez utiliser [str.translate][1], (mais lisez la suite pour les différences avec Python 3) :

line = line.translate(None, '!@#$')

ou le remplacement d'une expression régulière avec re.sub

import re
line = re.sub('[!@#$]', '', line)

Les caractères entre parenthèses constituent une classe de caractères. Tous les caractères de line qui font partie de cette classe sont remplacés par le second paramètre de sub : une chaîne vide.

En Python 3, les chaînes de caractères sont Unicode. Kevpie le mentionne dans un [commentaire][2] sur l'une des réponses, et c'est indiqué dans la [documentation de str.translate][1].

Lorsque vous appelez la méthode translate d'une chaîne Unicode, vous ne pouvez pas passer le second paramètre que nous avons utilisé ci-dessus. Vous ne pouvez pas non plus passer None comme premier paramètre, ou même une table de traduction de string.maketrans. A la place, vous devez passer un dictionnaire comme seul paramètre. Ce dictionnaire fait correspondre les valeurs ordinales des caractères (c'est-à-dire le résultat de l'appel de ord sur eux) aux valeurs ordinales des caractères qui devraient les remplacer, ou - ce qui est utile pour nous - None pour indiquer qu'ils devraient être supprimés.

Donc, pour faire la danse ci-dessus avec une chaîne Unicode, il faut appeler quelque chose comme

translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)

Ici, dict.fromkeys et map sont utilisés pour générer succinctement un dictionnaire contenant

{ord('!'): None, ord('@'): None, ...}

Encore plus simple, comme le dit une autre réponse, créer le dictionnaire sur place :

unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})

* Pour des raisons de compatibilité avec les versions antérieures de Python, vous pouvez créer une table de traduction "null" à passer à la place de "None" :

import string
line = line.translate(string.maketrans('', ''), '!@#$')

Ici, string.maketrans est utilisé pour créer une table de traduction, qui est juste une chaîne contenant les caractères avec des valeurs ordinales de 0 à 255.

[1] : https://docs.python.org/2/library/stdtypes.html#str.translate [2] : https://stackoverflow.com/questions/3939361/remove-specific-characters-from-a-string-in-python#comment-4205256

Commentaires (7)
line = line.translate(None, " ?.!/;:")
Commentaires (2)

Les chaînes de caractères sont immuables en Python. La méthode replace renvoie une nouvelle chaîne après le remplacement. Essayez :

for char in line:
    if char in " ?.!/;:":
        line = line.replace(char,'')
Commentaires (3)