@JG: J'ai gtk.Entry () et je veux que le multiply float y entre.
Jan Tojnar
1
@JanTojnar utilise la méthode re.sub selon la deuxième réponse et liste explicitement les caractères à conserver, par exemple re.sub ("[^ 0123456789 \.]", "", "Poo123.4and5fish")
Roger Heathcote
Réponses:
112
En Python 2. *, l'approche de loin la plus rapide est la .translateméthode:
string.maketransfait une table de traduction (une chaîne de longueur 256) qui dans ce cas est la même que ''.join(chr(x) for x in range(256))(juste plus rapide à faire ;-). .translateapplique la table de traduction (qui ici n'est pas pertinente car allsignifie essentiellement identité) ET supprime les caractères présents dans le deuxième argument - la partie clé.
.translatefonctionne très différemment sur les chaînes Unicode (et les chaînes en Python 3 - Je fais des questions de souhaits spécifiques , qui majeure à libération de Python est intéressant!) - pas tout à fait ce simple, pas tout à fait ce jeûne, mais encore tout à fait utilisable.
De retour à 2. *, la différence de performances est impressionnante ...:
$ python -mtimeit -s'import string; all=string.maketrans("", ""); nodig=all.translate(all, string.digits); x="aaa12333bb445bb54b5b52"''x.translate(all, nodig)'1000000 loops, best of 3:1.04 usec per loop
$ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"''re.sub(r"\D", "", x)'100000 loops, best of 3:7.9 usec per loop
Accélérer les choses de 7 à 8 fois n'est guère d'arachides, donc la translateméthode vaut la peine d'être connue et utilisée. L'autre approche non-ER populaire ...:
$ python -mtimeit -s'x="aaa12333bb445bb54b5b52"''"".join(i for i in x if i.isdigit())'100000 loops, best of 3:11.5 usec per loop
est 50% plus lent que RE, donc l' .translateapproche la bat de plus d'un ordre de grandeur.
Dans Python 3, ou pour Unicode, vous devez passer .translateun mappage (avec des ordinaux, et non des caractères directement, comme clés) qui renvoie Nonece que vous voulez supprimer. Voici un moyen pratique d'exprimer cela pour supprimer "tout sauf" quelques caractères:
import string
classDel:def __init__(self, keep=string.digits):
self.comp = dict((ord(c),c)for c in keep)def __getitem__(self, k):return self.comp.get(k)
DD =Del()
x='aaa12333bb445bb54b5b52'
x.translate(DD)
émet également '1233344554552'. Cependant, en mettant cela dans xx.py, nous avons ...:
$ python3.1-mtimeit -s'import re; x="aaa12333bb445bb54b5b52"''re.sub(r"\D", "", x)'100000 loops, best of 3:8.43 usec per loop
$ python3.1-mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"''x.translate(xx.DD)'10000 loops, best of 3:24.3 usec per loop
... ce qui montre que l'avantage de performance disparaît, pour ce genre de tâches de «suppression», et devient une diminution des performances.
@sunqiang, oui, absolument - il y a une raison pour laquelle Py3k est passé à Unicode en tant que type de chaîne de texte, au lieu de chaînes d'octets comme dans Py2 - même raison pour laquelle Java et C # ont toujours eu le même mème "string means unicode" ... des frais généraux, peut-être, mais BEAUCOUP meilleur support pour à peu près tout sauf l'anglais! -).
Alex Martelli
29
x.translate(None, string.digits)aboutit en fait 'aaabbbbbb', ce qui est le contraire de ce qui est prévu.
Tom Dalling
4
Faisant écho aux commentaires de Tom Dalling, votre premier exemple conserve tous les caractères indésirables - fait le contraire de ce que vous avez dit.
Chris Johnson le
3
@ RyanB.Lynch et al, la faute était avec un éditeur plus récent et deux autres utilisateurs qui ont approuvé cette modification , ce qui, en fait, est totalement faux. Revenu.
Nick T
1
remplaçant allbuiltin ... pas sûr!
Andy Hayden
197
Utilisez re.sub, comme ceci:
>>>import re
>>> re.sub('\D','','aas30dsa20')'3020'
\D correspond à n'importe quel caractère non numérique, donc le code ci-dessus remplace essentiellement chaque caractère non numérique de la chaîne vide.
Ou vous pouvez utiliser filter, comme ça (en Python 2):
>>> filter(str.isdigit,'aas30dsa20')'3020'
Puisque dans Python 3, filterrenvoie un itérateur au lieu de a list, vous pouvez utiliser ce qui suit à la place:
re est mal dans une tâche aussi simple, la deuxième est la meilleure que je pense, car les méthodes 'est ...' sont les plus rapides pour les cordes.
f0b0s
votre exemple de filtre est limité à py2k
SilentGhost
2
@ f0b0s-iu9-info: l'avez-vous chronométré? sur ma machine (py3k) re est deux fois plus rapide que le filtre avec isdigit, le générateur avec isdigtest à mi-chemin entre eux
SilentGhost
@SilentGhost: Merci, j'utilisais IDLE de py2k. C'est réglé maintenant.
João Silva
1
@asmaier Simplement utiliser rpour la chaîne brute:re.sub(r"\D+", "", "aas30dsa20")
J'obtiens un TypeError: translate () prend exactement un argument (2 donnés). Pourquoi cette question a été votée à la hausse dans son état actuel est assez frustrante.
Bobort
translate changé de python 2 à 3. La syntaxe utilisant cette méthode dans python 3 est x.translate (str.maketrans ('', '', string.digits)) et x.translate (str.maketrans ('', '' , string.ascii_letters)). Aucune de ces bandes n'espace blanc. Je ne recommanderais plus vraiment cette approche ...
ZaxR
5
L'op mentionne dans les commentaires qu'il souhaite conserver la décimale. Cela peut être fait avec la méthode re.sub (selon la seconde et la meilleure réponse à mon humble avis) en énumérant explicitement les caractères à conserver, par exemple
Dans mon code, je vérifie le nombre de périodes dans la chaîne d'entrée et déclenche une erreur s'il est supérieur à 1.
Roger Heathcote
4
Une version rapide pour Python 3:
# xx3.pyfrom collections import defaultdict
import string
_NoneType= type(None)def keeper(keep):
table = defaultdict(_NoneType)
table.update({ord(c): c for c in keep})return table
digit_keeper = keeper(string.digits)
Voici une comparaison des performances par rapport à l'expression régulière:
$ python3.3-mtimeit -s'import xx3; x="aaa12333bb445bb54b5b52"''x.translate(xx3.digit_keeper)'1000000 loops, best of 3:1.02 usec per loop
$ python3.3-mtimeit -s'import re; r = re.compile(r"\D"); x="aaa12333bb445bb54b5b52"''r.sub("", x)'100000 loops, best of 3:3.43 usec per loop
C'est donc un peu plus de 3 fois plus rapide que les regex, pour moi. C'est aussi plus rapide que class Delci-dessus, car defaultdictfait toutes ses recherches en C, plutôt qu'en Python (lent). Voici cette version sur mon même système, à titre de comparaison.
$ python3.3-mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"''x.translate(xx.DD)'100000 loops, best of 3:13.6 usec per loop
@SilentGhost c'est mon malentendu. l'avait corrigé merci :)
Gant
En fait, avec cette méthode, je ne pense pas que vous ayez besoin d'utiliser "join". filter(lambda x: x.isdigit(), s)a bien fonctionné pour moi. ... oh, c'est parce que j'utilise Python 2.7.
Pourquoi répétez-vous les deux méthodes deux fois? Et pourriez-vous décrire en quoi votre réponse est différente de celle acceptée?
Jan Tojnar
Les deux résultats le même résultat. Mais, je veux juste montrer que la jointure est plus rapide que la sous-méthode dans les résultats.
AnilReddy
Ils ne le font pas, votre code fait le contraire. Et vous avez aussi quatre mesures mais seulement deux méthodes.
Jan Tojnar
1
Vous pouvez lire chaque caractère. S'il s'agit d'un chiffre, incluez-le dans la réponse. La str.isdigit()méthode est un moyen de savoir si un caractère est un chiffre.
your_input ='12kjkh2nnk34l34'
your_output =''.join(c for c in your_input if c.isdigit())print(your_output)# '1223434'
Réponses:
En Python 2. *, l'approche de loin la plus rapide est la
.translate
méthode:string.maketrans
fait une table de traduction (une chaîne de longueur 256) qui dans ce cas est la même que''.join(chr(x) for x in range(256))
(juste plus rapide à faire ;-)..translate
applique la table de traduction (qui ici n'est pas pertinente carall
signifie essentiellement identité) ET supprime les caractères présents dans le deuxième argument - la partie clé..translate
fonctionne très différemment sur les chaînes Unicode (et les chaînes en Python 3 - Je fais des questions de souhaits spécifiques , qui majeure à libération de Python est intéressant!) - pas tout à fait ce simple, pas tout à fait ce jeûne, mais encore tout à fait utilisable.De retour à 2. *, la différence de performances est impressionnante ...:
Accélérer les choses de 7 à 8 fois n'est guère d'arachides, donc la
translate
méthode vaut la peine d'être connue et utilisée. L'autre approche non-ER populaire ...:est 50% plus lent que RE, donc l'
.translate
approche la bat de plus d'un ordre de grandeur.Dans Python 3, ou pour Unicode, vous devez passer
.translate
un mappage (avec des ordinaux, et non des caractères directement, comme clés) qui renvoieNone
ce que vous voulez supprimer. Voici un moyen pratique d'exprimer cela pour supprimer "tout sauf" quelques caractères:émet également
'1233344554552'
. Cependant, en mettant cela dans xx.py, nous avons ...:... ce qui montre que l'avantage de performance disparaît, pour ce genre de tâches de «suppression», et devient une diminution des performances.
la source
x.translate(None, string.digits)
aboutit en fait'aaabbbbbb'
, ce qui est le contraire de ce qui est prévu.all
builtin ... pas sûr!Utilisez
re.sub
, comme ceci:\D
correspond à n'importe quel caractère non numérique, donc le code ci-dessus remplace essentiellement chaque caractère non numérique de la chaîne vide.Ou vous pouvez utiliser
filter
, comme ça (en Python 2):Puisque dans Python 3,
filter
renvoie un itérateur au lieu de alist
, vous pouvez utiliser ce qui suit à la place:la source
isdigit
, le générateur avecisdigt
est à mi-chemin entre euxr
pour la chaîne brute:re.sub(r"\D+", "", "aas30dsa20")
Une autre variante de générateur.
la source
Vous pouvez utiliser le filtre:
Sur python3.0, vous devez rejoindre ceci (un peu moche :()
la source
str
enlist
pour vous assurer qu'il fonctionne à la fois sur py2 et py3:''.join(filter(lambda x: x.isdigit(), list("dasdasd2313dsa")))
dans le sens de la réponse de Bayer:
la source
-
n'est pas un chiffre.Vous pouvez facilement le faire en utilisant Regex
la source
supprimera tous les chiffres de la chaîne. Pour supprimer des lettres et conserver les chiffres, procédez comme suit:
la source
TypeError
: translate () prend exactement un argument (2 donnés). Pourquoi cette question a été votée à la hausse dans son état actuel est assez frustrante.L'op mentionne dans les commentaires qu'il souhaite conserver la décimale. Cela peut être fait avec la méthode re.sub (selon la seconde et la meilleure réponse à mon humble avis) en énumérant explicitement les caractères à conserver, par exemple
la source
Une version rapide pour Python 3:
Voici une comparaison des performances par rapport à l'expression régulière:
C'est donc un peu plus de 3 fois plus rapide que les regex, pour moi. C'est aussi plus rapide que
class Del
ci-dessus, cardefaultdict
fait toutes ses recherches en C, plutôt qu'en Python (lent). Voici cette version sur mon même système, à titre de comparaison.la source
Utilisez une expression de générateur:
la source
''.join(n for n in foo if n.isdigit())
Moche mais fonctionne:
la source
list(s)
?filter(lambda x: x.isdigit(), s)
a bien fonctionné pour moi. ... oh, c'est parce que j'utilise Python 2.7.J'avais observé que la jointure est plus rapide que les sous.
la source
Vous pouvez lire chaque caractère. S'il s'agit d'un chiffre, incluez-le dans la réponse. La
str.isdigit()
méthode est un moyen de savoir si un caractère est un chiffre.la source
Pas une seule ligne mais très simple:
la source
J'ai utilisé ça.
'letters'
doit contenir toutes les lettres dont vous souhaitez vous débarrasser:Output = Input.translate({ord(i): None for i in 'letters'}))
Exemple:
Input = "I would like 20 dollars for that suit" Output = Input.translate({ord(i): None for i in 'abcdefghijklmnopqrstuvwxzy'})) print(Output)
Production:
20
la source