@JG: Mam gtk.Entry () i chcę wprowadzić do niego multiply float.
Jan Tojnar
1
@JanTojnar używa metody re.sub zgodnie z odpowiedzią 2 i wyraźnie podaje, które znaki mają być zachowane, np. Re.sub ("[^ 0123456789 \.]", "", "Poo123.4and5fish")
Roger Heathcote
Odpowiedzi:
112
W Pythonie 2. * zdecydowanie najszybszym podejściem jest .translatemetoda:
string.maketranstworzy tablicę tłumaczeń (ciąg o długości 256), która w tym przypadku jest taka sama jak ''.join(chr(x) for x in range(256))(tylko szybsza do wykonania ;-). .translatestosuje tabelę tłumaczeń (która tutaj nie ma znaczenia, ponieważ allzasadniczo oznacza tożsamość) ORAZ usuwa znaki obecne w drugim argumencie - części kluczowej.
.translatedziała bardzo różnie na Unicode (i smyczki w Pythonie 3 - I zrobić pytania życzenie określony których głównym uwalnianiu Pythona ma znaczenie!) - nie całkiem to proste, to nie dość szybko, choć nadal bardzo użyteczny.
Wracając do 2. *, różnica w wydajności jest imponująca ...:
$ 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
Przyspieszenie tempa 7-8 razy to nie grosze, więc translatewarto znać i stosować tę metodę. Inne popularne podejście non-RE ...:
$ python -mtimeit -s'x="aaa12333bb445bb54b5b52"''"".join(i for i in x if i.isdigit())'100000 loops, best of 3:11.5 usec per loop
jest o 50% wolniejszy niż RE, więc .translatepodejście przebija go o ponad rząd wielkości.
W Pythonie 3 lub w Unicode musisz przekazać .translateodwzorowanie (z liczbami porządkowymi, a nie znakami bezpośrednio, jako klucze), które zwraca Noneto, co chcesz usunąć. Oto wygodny sposób wyrażenia tego w celu usunięcia „wszystkiego oprócz” kilku znaków:
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)
również emituje '1233344554552'. Jednak umieszczając to w xx.py mamy ...:
$ 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
... co pokazuje, że przewaga wydajności znika w przypadku tego rodzaju zadań „usuwania” i staje się spadkiem wydajności.
@sunqiang, tak, absolutnie - istnieje powód, dla którego Py3k przeszedł na Unicode jako typ ciągu tekstowego, zamiast ciągów bajtów, jak w Py2 - ten sam powód, dla którego Java i C # zawsze miały ten sam mem "ciąg znaków oznacza unicode" ... może trochę narzutów, ale DUŻO lepsze wsparcie dla prawie wszystkiego oprócz angielskiego! -).
Alex Martelli
29
x.translate(None, string.digits)w rzeczywistości skutkuje 'aaabbbbbb', co jest przeciwieństwem tego, co jest zamierzone.
Tom Dalling
4
Powtarzając komentarze Toma Dallinga, twój pierwszy przykład zachowuje wszystkie niepożądane postacie - robi odwrotność tego, co powiedziałeś.
Chris Johnson,
3
@ RyanB.Lynch i in., Wina była spowodowana późniejszym redaktorem i dwoma innymi użytkownikami, którzy zatwierdzili tę zmianę , co w rzeczywistości jest całkowicie błędne. Przywrócony.
Nick T
1
nadpisywanie allwbudowanego ... nie jestem tego pewien!
Andy Hayden
197
Użyj re.sub, tak jak to:
>>>import re
>>> re.sub('\D','','aas30dsa20')'3020'
\D dopasowuje dowolny znak niecyfrowy, więc powyższy kod zasadniczo zastępuje każdy znak niecyfrowy w pustym łańcuchu.
Lub możesz użyć filter, na przykład (w Pythonie 2):
>>> filter(str.isdigit,'aas30dsa20')'3020'
Ponieważ w Pythonie 3 filterzwraca iterator zamiast alist , możesz zamiast tego użyć następującego:
re jest zło w tak prostym zadaniu, drugie jest najlepsze, jak sądzę, ponieważ metody „jest…” są najszybsze dla strun.
f0b0s
Twój przykład filtru jest ograniczony do py2k
SilentGhost
2
@ f0b0s-iu9-info: czy to zaplanowałeś? na moim komputerze (py3k) re jest dwa razy szybszy niż filtr z isdigit, generator w isdigtpołowie drogi między nimi
SilentGhost
@SilentGhost: Dzięki, korzystałem z IDLE z py2k. To jest teraz naprawione.
João Silva
1
@asmaier Po prostu użyj rdla nieprzetworzonego ciągu:re.sub(r"\D+", "", "aas30dsa20")
Otrzymuję TypeError: translate () przyjmuje dokładnie jeden argument (podane 2). Dlaczego głosowano za tym pytaniem w obecnym stanie, jest dość frustrujące.
Bobort
translate zmieniono z pythona 2 na 3. Składnia używająca tej metody w pythonie 3 to x.translate (str.maketrans ('', '', string.digits)) i x.translate (str.maketrans ('', '' , string.ascii_letters)). Żaden z tych pasków nie jest biały. Nie polecałbym już tego podejścia ...
ZaxR
5
Opcja wspomina w komentarzach, że chce zachować miejsce dziesiętne. Można to zrobić za pomocą metody re.sub (zgodnie z drugą i najlepszą odpowiedzią IMHO), jawnie wymieniając znaki, które mają być zachowane, np.
W moim kodzie sprawdzam liczbę okresów w ciągu wejściowym i zgłaszam błąd, jeśli jest więcej niż 1.
Roger Heathcote
4
Szybka wersja dla Pythona 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)
Oto porównanie wydajności z wyrażeniem regularnym:
$ 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
Jak dla mnie jest to trochę ponad 3 razy szybsze niż regex. Jest również szybszy niż class Delpowyżej, ponieważ defaultdictwszystkie wyszukiwania wykonuje w C, a nie (powolny) Python. Oto ta wersja w moim systemie dla porównania.
$ python3.3-mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"''x.translate(xx.DD)'100000 loops, best of 3:13.6 usec per loop
@SilentGhost to moje nieporozumienie. miał to poprawione dzięki :)
Gant
Właściwie przy tej metodzie nie sądzę, abyś musiał używać opcji „dołącz”. filter(lambda x: x.isdigit(), s)działało dobrze dla mnie. ... och, to dlatego, że używam Pythona 2.7.
Odpowiedzi:
W Pythonie 2. * zdecydowanie najszybszym podejściem jest
.translate
metoda:string.maketrans
tworzy tablicę tłumaczeń (ciąg o długości 256), która w tym przypadku jest taka sama jak''.join(chr(x) for x in range(256))
(tylko szybsza do wykonania ;-)..translate
stosuje tabelę tłumaczeń (która tutaj nie ma znaczenia, ponieważall
zasadniczo oznacza tożsamość) ORAZ usuwa znaki obecne w drugim argumencie - części kluczowej..translate
działa bardzo różnie na Unicode (i smyczki w Pythonie 3 - I zrobić pytania życzenie określony których głównym uwalnianiu Pythona ma znaczenie!) - nie całkiem to proste, to nie dość szybko, choć nadal bardzo użyteczny.Wracając do 2. *, różnica w wydajności jest imponująca ...:
Przyspieszenie tempa 7-8 razy to nie grosze, więc
translate
warto znać i stosować tę metodę. Inne popularne podejście non-RE ...:jest o 50% wolniejszy niż RE, więc
.translate
podejście przebija go o ponad rząd wielkości.W Pythonie 3 lub w Unicode musisz przekazać
.translate
odwzorowanie (z liczbami porządkowymi, a nie znakami bezpośrednio, jako klucze), które zwracaNone
to, co chcesz usunąć. Oto wygodny sposób wyrażenia tego w celu usunięcia „wszystkiego oprócz” kilku znaków:również emituje
'1233344554552'
. Jednak umieszczając to w xx.py mamy ...:... co pokazuje, że przewaga wydajności znika w przypadku tego rodzaju zadań „usuwania” i staje się spadkiem wydajności.
źródło
x.translate(None, string.digits)
w rzeczywistości skutkuje'aaabbbbbb'
, co jest przeciwieństwem tego, co jest zamierzone.all
wbudowanego ... nie jestem tego pewien!Użyj
re.sub
, tak jak to:\D
dopasowuje dowolny znak niecyfrowy, więc powyższy kod zasadniczo zastępuje każdy znak niecyfrowy w pustym łańcuchu.Lub możesz użyć
filter
, na przykład (w Pythonie 2):Ponieważ w Pythonie 3
filter
zwraca iterator zamiast alist
, możesz zamiast tego użyć następującego:źródło
isdigit
, generator wisdigt
połowie drogi między nimir
dla nieprzetworzonego ciągu:re.sub(r"\D+", "", "aas30dsa20")
Inny wariant generatora.
źródło
Możesz użyć filtra:
Na pythonie 3.0 musisz dołączyć do tego (trochę brzydkie :()
źródło
str
na,list
aby upewnić się, że działa zarówno na py2, jak i py3:''.join(filter(lambda x: x.isdigit(), list("dasdasd2313dsa")))
zgodnie z odpowiedzią Bayera:
źródło
-
nie jest cyfrą.Możesz to łatwo zrobić za pomocą Regex
źródło
usunie wszystkie cyfry z ciągu. Aby usunąć litery i zachować cyfry, wykonaj następujące czynności:
źródło
TypeError
: translate () przyjmuje dokładnie jeden argument (podane 2). Dlaczego głosowano za tym pytaniem w obecnym stanie, jest dość frustrujące.Opcja wspomina w komentarzach, że chce zachować miejsce dziesiętne. Można to zrobić za pomocą metody re.sub (zgodnie z drugą i najlepszą odpowiedzią IMHO), jawnie wymieniając znaki, które mają być zachowane, np.
źródło
Szybka wersja dla Pythona 3:
Oto porównanie wydajności z wyrażeniem regularnym:
Jak dla mnie jest to trochę ponad 3 razy szybsze niż regex. Jest również szybszy niż
class Del
powyżej, ponieważdefaultdict
wszystkie wyszukiwania wykonuje w C, a nie (powolny) Python. Oto ta wersja w moim systemie dla porównania.źródło
Użyj wyrażenia generatora:
źródło
''.join(n for n in foo if n.isdigit())
Brzydki, ale działa:
źródło
list(s)
?filter(lambda x: x.isdigit(), s)
działało dobrze dla mnie. ... och, to dlatego, że używam Pythona 2.7.Zauważyłem, że łączenie jest szybsze niż sub.
źródło
Możesz przeczytać każdą postać. Jeśli jest cyfrą, dołącz ją do odpowiedzi.
str.isdigit()
Metoda jest sposobem, aby wiedzieć, czy znak jest cyfra.źródło
Nie jest to jedna wkładka, ale bardzo prosta:
źródło
Użyłem tego.
'letters'
powinien zawierać wszystkie litery, których chcesz się pozbyć:Output = Input.translate({ord(i): None for i in 'letters'}))
Przykład:
Input = "I would like 20 dollars for that suit" Output = Input.translate({ord(i): None for i in 'abcdefghijklmnopqrstuvwxzy'})) print(Output)
Wynik:
20
źródło