web-dev-qa-db-fra.com

string.translate () avec des données unicode en python

J'ai 3 API qui renvoient des données Json à 3 variables de dictionnaire. Je prends certaines des valeurs du dictionnaire pour les traiter. J'ai lu les valeurs spécifiques que je veux dans la liste valuelist. L'une des étapes consiste à supprimer la ponctuation. J'utilise normalement string.translate(None, string.punctuation) pour ce processus, mais parce que les données du dictionnaire sont unicode, j'obtiens l'erreur: 

    wordlist = [s.translate(None, string.punctuation)for s in valuelist]
TypeError: translate() takes exactly one argument (2 given)

Y a-t-il un moyen de contourner ceci? Soit en codant l’unicode, soit en remplaçant string.translate?

23
adohertyd

La méthode translate fonctionne différemment sur les objets Unicode et sur les objets chaîne d'octets:

 >>> help (unicode.translate) 

 S.translate (table) -> unicode 

 Renvoie une copie de la chaîne S, où tous les caractères ont été mappés 
 à travers la table de traduction donnée, qui doit être un mappage de 
 Les ordinaux Unicode en ordinaux Unicode, de chaînes Unicode ou de Aucun .
 Les caractères non mappés ne sont pas modifiés. Les caractères associés à Aucun 
 Sont supprimés .

Donc, votre exemple deviendrait:

remove_punctuation_map = dict((ord(char), None) for char in string.punctuation)
Word_list = [s.translate(remove_punctuation_map) for s in value_list]

Notez cependant que string.punctuation ne contient que la ponctuation ASCII. Full Unicode a beaucoup plus de caractères de ponctuation, mais tout dépend de votre cas d'utilisation.

32
Simon Sapin

J'ai remarqué que string.translate est obsolète. Comme vous supprimez la ponctuation et ne traduisez pas réellement les caractères, vous pouvez utiliser la fonction re.sub.

    >>> import re

    >>> s1="this.is a.string, with; (punctuation)."
    >>> s1
    'this.is a.string, with; (punctuation).'
    >>> re.sub("[\.\t\,\:;\(\)\.]", "", s1, 0, 0)
    'thisis astring with punctuation'
    >>>
6
ncultra

Dans cette version, vous pouvez faire ses lettres à d’autres 

def trans(to_translate):
    tabin = u'привет'
    tabout = u'тевирп'
    tabin = [ord(char) for char in tabin]
    translate_table = dict(Zip(tabin, tabout))
    return to_translate.translate(translate_table)
3
madjardi

Alors que je suis tombé sur le même problème et que la réponse de Simon m'a aidé à résoudre mon cas, j'ai pensé montrer un exemple plus simple, juste pour clarifier:

from collections import defaultdict

Et pour la traduction, dites que vous souhaitez supprimer les caractères "@" et "\ r":

remove_chars_map = defaultdict()
remove_chars_map['@'] = None
remove_chars_map['\r'] = None

new_string = old_string.translate(remove_chars_map)

Et un exemple:

old_string = "Word1 @ \\ Word2 @\r Word3 @ \"

new_string = "Word1 Word2 Word3"

'@' et '\ r' supprimés

1
John Koumarelas

Le module Python re permet d'utiliser une fonction en tant qu'argument de remplacement , qui devrait prendre un objet Match et renvoyer un objet de remplacement approprié. Nous pouvons utiliser cette fonction pour créer une fonction de traduction de caractères personnalisée:

import re

def mk_replacer(oldchars, newchars):
    """A function to build a replacement function"""
    mapping = dict(Zip(oldchars, newchars))
    def replacer(match):
        """A replacement function to pass to re.sub()"""
        return mapping.get(match.group(0), "")
    return replacer

Un exemple. Faites correspondre toutes les lettres minuscules ([a-z]), traduisez respectivement "h" et "i" en "H" et "I", supprimez les autres correspondances:

>>> re.sub("[a-z]", mk_replacer("hi", "HI"), "hail")
'HI'

Comme vous pouvez le constater, il peut être utilisé avec des ensembles de remplacement courts (incomplets) et peut être utilisé pour supprimer certains caractères.

Un exemple Unicode:

>>> re.sub("[\W]", mk_replacer(u'\u0435\u0438\u043f\u0440\u0442\u0432', u"EIPRTV"), u'\u043f\u0440\u0438\u0432\u0435\u0442')
u'PRIVET'
1
sastanin