@JG: Saya memiliki gtk.Entry () dan saya ingin multiply float masuk ke dalamnya.
Jan Tojnar
1
@JanTojnar menggunakan metode re.sub sesuai jawaban dua dan secara eksplisit mencantumkan karakter mana yang akan disimpan misalnya re.sub ("[^ 0123456789 \.]", "", "Poo123.4and5fish")
Roger Heathcote
Jawaban:
112
Dalam Python 2. *, sejauh ini pendekatan tercepat adalah .translatemetode:
string.maketransmembuat tabel terjemahan (string dengan panjang 256) yang dalam hal ini sama dengan ''.join(chr(x) for x in range(256))(hanya lebih cepat membuatnya ;-). .translatemenerapkan tabel terjemahan (yang di sini tidak relevan karena allpada dasarnya berarti identitas) DAN menghapus karakter yang ada di argumen kedua - bagian kunci.
.translatebekerja sangat berbeda pada string Unicode (dan string di Python 3 - Saya melakukan pertanyaan keinginan tertentu yang besar-rilis Python adalah kepentingan!) - tidak cukup sederhana ini, tidak cukup cepat ini, meskipun masih cukup bermanfaat.
Kembali ke 2. *, perbedaan kinerja sangat mengesankan ...:
$ 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
Mempercepat sebanyak 7-8 kali bukanlah hal yang mudah, jadi translatemetode ini layak untuk diketahui dan digunakan. Pendekatan non-RE populer lainnya ...:
$ python -mtimeit -s'x="aaa12333bb445bb54b5b52"''"".join(i for i in x if i.isdigit())'100000 loops, best of 3: 11.5 usec per loop
adalah 50% lebih lambat dari RE, sehingga .translatependekatan mengalahkannya dengan urutan besarnya.
Di Python 3, atau untuk Unicode, Anda perlu meneruskan .translatepemetaan (dengan ordinal, bukan karakter secara langsung, sebagai kunci) yang mengembalikan Noneapa yang ingin Anda hapus. Berikut cara mudah untuk mengungkapkannya untuk menghapus "semuanya kecuali" beberapa karakter:
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)
juga memancarkan '1233344554552'. Namun, meletakkan ini di xx.py kita memiliki ...:
$ 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
... yang menunjukkan keuntungan kinerja menghilang, untuk jenis tugas "penghapusan", dan menjadi penurunan kinerja.
@sunqiang, ya, tentu saja - ada alasan Py3k beralih ke Unicode sebagai tipe string teks THE, bukan string byte seperti di Py2 - alasan yang sama Java dan C # selalu memiliki meme "string berarti unicode" yang sama ... beberapa overhead, mungkin, tetapi dukungan yang JAUH lebih baik untuk apa saja kecuali bahasa Inggris! -).
Alex Martelli
29
x.translate(None, string.digits)sebenarnya menghasilkan 'aaabbbbbb', yang merupakan kebalikan dari apa yang dimaksudkan.
Tom Dalling
4
Mengomentari komentar dari Tom Dalling, contoh pertama Anda menyimpan semua karakter yang tidak diinginkan - berlawanan dengan apa yang Anda katakan.
Chris Johnson
3
@ RyanB.Lynch dkk, kesalahannya ada pada editor selanjutnya dan dua pengguna lain yang menyetujui edit tersebut , yang, sebenarnya, sepenuhnya salah. Dikembalikan.
Nick T
2
overriding allbuiltin ... tidak yakin tentang itu!
Andy Hayden
202
Gunakan re.sub, seperti ini:
>>> import re
>>> re.sub('\D', '', 'aas30dsa20')
'3020'
\D cocok dengan karakter non-digit apa pun, jadi, kode di atas, pada dasarnya menggantikan setiap karakter non-digit untuk string kosong.
Atau Anda dapat menggunakan filter, seperti (dengan Python 2):
>>> filter(str.isdigit, 'aas30dsa20')
'3020'
Karena di Python 3, filtermengembalikan iterator alih-alih a list, Anda dapat menggunakan yang berikut ini:
re jahat dalam tugas sederhana seperti itu, yang kedua adalah yang terbaik menurut saya, karena metode 'adalah ...' adalah yang tercepat untuk string.
f0b0s
contoh filter Anda terbatas pada py2k
SilentGhost
2
@ f0b0s-iu9-info: apakah Anda menghitung waktunya? pada mesin saya (py3k) dua kali lebih cepat daripada filter dengan isdigit, generator dengan isdigtsetengah jalan di antara mereka
SilentGhost
@SilentGhost: Terima kasih, saya menggunakan IDLE dari py2k. Sudah diperbaiki sekarang.
João Silva
1
@asmaier Cukup gunakan runtuk string mentah:re.sub(r"\D+", "", "aas30dsa20")
Membunuhnya .. + 1 Akan lebih baik jika lamda digunakan
Barath Ravikumar
Jika Anda ingin memasukkan karakter khusus apa pun, misalnya menyertakan negatif atau desimal - lakukan ini:s = ''.join(i for i in s if i.isdigit() or i in '-./\\')
Eugene Chabanov
17
Anda dapat menggunakan filter:
filter(lambda x: x.isdigit(), "dasdasd2313dsa")
Di python3.0 Anda harus bergabung dengan ini (agak jelek :()
Saya mendapatkan TypeError: translate () mengambil tepat satu argumen (2 diberikan). Mengapa pertanyaan ini mendapat suara positif dalam kondisinya saat ini cukup membuat frustrasi.
Bobort
translate diubah dari python 2 menjadi 3. Sintaks yang menggunakan metode ini di python 3 adalah x.translate (str.maketrans ('', '', string.digits)) dan x.translate (str.maketrans ('', '' , string.ascii_letters)). Tak satu pun dari strip ini ruang putih. Saya tidak akan merekomendasikan pendekatan ini lagi ...
ZaxR
6
Op tersebut menyebutkan di komentar bahwa dia ingin menyimpan tempat desimal. Ini dapat dilakukan dengan metode re.sub (sesuai dengan jawaban terbaik kedua dan IMHO) dengan secara eksplisit mencantumkan karakter yang akan disimpan misalnya
Dalam kode saya, saya memeriksa jumlah periode dalam string input dan meningkatkan kesalahan jika itu lebih dari 1.
Roger Heathcote
4
Versi cepat untuk Python 3:
# xx3.pyfrom collections import defaultdict
import string
_NoneType = type(None)
defkeeper(keep):
table = defaultdict(_NoneType)
table.update({ord(c): c for c in keep})
return table
digit_keeper = keeper(string.digits)
Berikut perbandingan performa vs. regex:
$ 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
Jadi ini sedikit lebih dari 3 kali lebih cepat daripada regex, bagi saya. Ini juga lebih cepat daripada di class Delatas, karena defaultdictsemua pencariannya di C, daripada Python (lambat). Ini versi itu di sistem saya yang sama, untuk perbandingan.
$ python3.3 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"''x.translate(xx.DD)'100000 loops, best of 3: 13.6 usec per loop
@SilentGost itu kesalahpahaman saya. sudah diperbaiki terima kasih :)
Gant
Sebenarnya, dengan metode ini, saya rasa Anda tidak perlu menggunakan "gabung". filter(lambda x: x.isdigit(), s)bekerja dengan baik untuk saya. ... oh, itu karena saya menggunakan Python 2.7.
Bobort
2
Anda dapat membaca setiap karakter. Jika berupa digit, masukkan ke dalam jawaban. The str.isdigit()Metode adalah cara untuk mengetahui apakah karakter adalah digit.
your_input = '12kjkh2nnk34l34'
your_output = ''.join(c for c in your_input if c.isdigit())
print(your_output) # '1223434'
my_string="sdfsdfsdfsfsdf353dsg345435sdfs525436654.dgg("
my_string=''.join((ch if ch in'0123456789'else'') for ch in my_string)
print(output:+my_string)
Jawaban:
Dalam Python 2. *, sejauh ini pendekatan tercepat adalah
.translate
metode:>>> x='aaa12333bb445bb54b5b52' >>> import string >>> all=string.maketrans('','') >>> nodigs=all.translate(all, string.digits) >>> x.translate(all, nodigs) '1233344554552' >>>
string.maketrans
membuat tabel terjemahan (string dengan panjang 256) yang dalam hal ini sama dengan''.join(chr(x) for x in range(256))
(hanya lebih cepat membuatnya ;-)..translate
menerapkan tabel terjemahan (yang di sini tidak relevan karenaall
pada dasarnya berarti identitas) DAN menghapus karakter yang ada di argumen kedua - bagian kunci..translate
bekerja sangat berbeda pada string Unicode (dan string di Python 3 - Saya melakukan pertanyaan keinginan tertentu yang besar-rilis Python adalah kepentingan!) - tidak cukup sederhana ini, tidak cukup cepat ini, meskipun masih cukup bermanfaat.Kembali ke 2. *, perbedaan kinerja sangat mengesankan ...:
$ 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
Mempercepat sebanyak 7-8 kali bukanlah hal yang mudah, jadi
translate
metode ini layak untuk diketahui dan digunakan. Pendekatan non-RE populer lainnya ...:$ python -mtimeit -s'x="aaa12333bb445bb54b5b52"' '"".join(i for i in x if i.isdigit())' 100000 loops, best of 3: 11.5 usec per loop
adalah 50% lebih lambat dari RE, sehingga
.translate
pendekatan mengalahkannya dengan urutan besarnya.Di Python 3, atau untuk Unicode, Anda perlu meneruskan
.translate
pemetaan (dengan ordinal, bukan karakter secara langsung, sebagai kunci) yang mengembalikanNone
apa yang ingin Anda hapus. Berikut cara mudah untuk mengungkapkannya untuk menghapus "semuanya kecuali" beberapa karakter:import string class Del: 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)
juga memancarkan
'1233344554552'
. Namun, meletakkan ini di xx.py kita memiliki ...:$ 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
... yang menunjukkan keuntungan kinerja menghilang, untuk jenis tugas "penghapusan", dan menjadi penurunan kinerja.
sumber
x.translate(None, string.digits)
sebenarnya menghasilkan'aaabbbbbb'
, yang merupakan kebalikan dari apa yang dimaksudkan.all
builtin ... tidak yakin tentang itu!Gunakan
re.sub
, seperti ini:>>> import re >>> re.sub('\D', '', 'aas30dsa20') '3020'
\D
cocok dengan karakter non-digit apa pun, jadi, kode di atas, pada dasarnya menggantikan setiap karakter non-digit untuk string kosong.Atau Anda dapat menggunakan
filter
, seperti (dengan Python 2):>>> filter(str.isdigit, 'aas30dsa20') '3020'
Karena di Python 3,
filter
mengembalikan iterator alih-alih alist
, Anda dapat menggunakan yang berikut ini:>>> ''.join(filter(str.isdigit, 'aas30dsa20')) '3020'
sumber
isdigit
, generator denganisdigt
setengah jalan di antara merekar
untuk string mentah:re.sub(r"\D+", "", "aas30dsa20")
s=''.join(i for i in s if i.isdigit())
Varian generator lain.
sumber
s = ''.join(i for i in s if i.isdigit() or i in '-./\\')
Anda dapat menggunakan filter:
filter(lambda x: x.isdigit(), "dasdasd2313dsa")
Di python3.0 Anda harus bergabung dengan ini (agak jelek :()
''.join(filter(lambda x: x.isdigit(), "dasdasd2313dsa"))
sumber
str
kelist
untuk memastikannya berfungsi pada py2 dan py3:''.join(filter(lambda x: x.isdigit(), list("dasdasd2313dsa")))
di sepanjang garis jawaban bayer:
''.join(i for i in s if i.isdigit())
sumber
-
bukan digit.Anda dapat dengan mudah melakukannya menggunakan Regex
>>> import re >>> re.sub("\D","","£70,000") 70000
sumber
x.translate(None, string.digits)
akan menghapus semua digit dari string. Untuk menghapus huruf dan menyimpan angka, lakukan ini:
x.translate(None, string.letters)
sumber
TypeError
: translate () mengambil tepat satu argumen (2 diberikan). Mengapa pertanyaan ini mendapat suara positif dalam kondisinya saat ini cukup membuat frustrasi.Op tersebut menyebutkan di komentar bahwa dia ingin menyimpan tempat desimal. Ini dapat dilakukan dengan metode re.sub (sesuai dengan jawaban terbaik kedua dan IMHO) dengan secara eksplisit mencantumkan karakter yang akan disimpan misalnya
>>> re.sub("[^0123456789\.]","","poo123.4and5fish") '123.45'
sumber
Versi cepat untuk Python 3:
# xx3.py from 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)
Berikut perbandingan performa vs. regex:
$ 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
Jadi ini sedikit lebih dari 3 kali lebih cepat daripada regex, bagi saya. Ini juga lebih cepat daripada di
class Del
atas, karenadefaultdict
semua pencariannya di C, daripada Python (lambat). Ini versi itu di sistem saya yang sama, untuk perbandingan.$ python3.3 -mtimeit -s'import xx; x="aaa12333bb445bb54b5b52"' 'x.translate(xx.DD)' 100000 loops, best of 3: 13.6 usec per loop
sumber
Gunakan ekspresi generator:
>>> s = "foo200bar" >>> new_s = "".join(i for i in s if i in "0123456789")
sumber
''.join(n for n in foo if n.isdigit())
Jelek tapi berhasil:
>>> s 'aaa12333bb445bb54b5b52' >>> a = ''.join(filter(lambda x : x.isdigit(), s)) >>> a '1233344554552' >>>
sumber
list(s)
?filter(lambda x: x.isdigit(), s)
bekerja dengan baik untuk saya. ... oh, itu karena saya menggunakan Python 2.7.Anda dapat membaca setiap karakter. Jika berupa digit, masukkan ke dalam jawaban. The
str.isdigit()
Metode adalah cara untuk mengetahui apakah karakter adalah digit.your_input = '12kjkh2nnk34l34' your_output = ''.join(c for c in your_input if c.isdigit()) print(your_output) # '1223434'
sumber
$ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'
$ python -mtimeit -s'import re; x="aaa12333bb445bb54b5b52"' 're.sub(r"\D", "", x)'
$ python -mtimeit -s'import re; x="aaa12333bab445bb54b5b52"' '"".join(re.findall("[a-z]+",x))'
Saya telah mengamati bahwa join lebih cepat daripada sub.
sumber
Bukan satu baris tapi sangat sederhana:
buffer = "" some_str = "aas30dsa20" for char in some_str: if not char.isdigit(): buffer += char print( buffer )
sumber
Saya menggunakan ini.
'letters'
harus berisi semua huruf yang ingin Anda singkirkan:Output = Input.translate({ord(i): None for i in 'letters'}))
Contoh:
Input = "I would like 20 dollars for that suit" Output = Input.translate({ord(i): None for i in 'abcdefghijklmnopqrstuvwxzy'})) print(Output)
Keluaran:
20
sumber
my_string="sdfsdfsdfsfsdf353dsg345435sdfs525436654.dgg(" my_string=''.join((ch if ch in '0123456789' else '') for ch in my_string) print(output:+my_string)
sumber