Di Python, bagaimana saya bisa mengurai numerik string seperti "545.2222"
untuk yang sesuai float nilai, 545.2222
? Atau mengurai string "31"
ke integer, 31
?
Aku hanya ingin tahu bagaimana untuk mengurai pelampung str
untuk yang mengambang
, dan (terpisah) an int str
ke int
.
def is_float(value):
try:
float(value)
return True
except:
return False
Lebih lama dan lebih akurat nama untuk fungsi ini bisa: is_convertible_to_float(nilai)
val is_float(val) Note
-------------------- ---------- --------------------------------
"" False Blank string
"127" True Passed string
True True Pure sweet Truth
"True" False Vile contemptible lie
False True So false it becomes true
"123.456" True Decimal
" -127 " True Spaces trimmed
"\t\n12\r\n" True whitespace ignored
"NaN" True Not a number
"NaNanananaBATMAN" False I am Batman
"-iNF" True Negative infinity
"123.E4" True Exponential notation
".1" True mantissa only
"1,234" False Commas gtfo
u'\x30' True Unicode is fine.
"NULL" False Null is not special
0x3fade True Hexadecimal
"6e7777777777777" True Shrunk to infinity
"1.797693e+308" True This is max value
"infinity" True Same as inf
"infinityandBEYOND" False Extra characters wreck it
"12.34.56" False Only one dot allowed
u'四' False Japanese '4' is not a float.
"#56" False Pound sign
"56%" False Percent of what?
"0E0" True Exponential, move dot 0 places
0**0 True 0___0 Exponentiation
"-5e-5" True Raise to a negative number
"+1e1" True Plus is OK with exponent
"+1e1^5" False Fancy exponent not interpreted
"+1e1.3" False No decimals in exponent
"-+1" False Make up your mind
"(1)" False Parenthesis is bad
Anda pikir anda tahu apa angka-angka tersebut? Anda yang tidak begitu baik seperti yang anda pikirkan! Bukan kejutan besar.
Penangkapan luas pengecualian dengan cara ini, membunuh burung kenari dan menelan pengecualian menciptakan kemungkinan kecil yang masih berlaku mengapung sebagai string akan mengembalikan false. The float(...)
baris kode dapat gagal untuk setiap seribu alasan-alasan yang tidak ada hubungannya dengan isi dari string. Tapi jika anda're menulis kehidupan-perangkat lunak penting dalam duck-typing prototipe bahasa seperti Python, maka anda've punya banyak masalah yang lebih besar.
Ini adalah metode lain yang layak untuk disebutkan di sini, ast.literal_eval:
Ini dapat digunakan untuk aman mengevaluasi string yang mengandung ekspresi Python dari sumber terpercaya tanpa perlu mengurai nilai-nilai diri sendiri.
Artinya, yang aman 'eval'
>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
Anda harus mempertimbangkan kemungkinan koma dalam representasi string dari suatu jumlah, untuk kasus-kasus seperti float("545,545.2222")
yang melempar pengecualian. Sebaliknya, gunakan metode di lokal
untuk mengkonversi string ke angka dan menafsirkan tanda koma dengan benar. Lokal.atof
metode mengkonversi ke mengapung dalam satu langkah sekali lokal yang telah ditetapkan untuk jumlah yang diinginkan konvensi.
Contoh 1 -- Amerika Serikat konvensi nomor
Di Amerika Serikat dan INGGRIS, koma dapat digunakan sebagai pemisah ribuan. Dalam contoh ini dengan lokal Amerika, koma ditangani dengan baik sebagai pemisah:
>>> import locale
>>> a = u'545,545.2222'
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.atof(a)
545545.2222
>>> int(locale.atof(a))
545545
>>>
Contoh 2 -- Eropa konvensi nomor
Di sebagian besar negara-negara dunia]1, tanda koma digunakan untuk tanda desimal bukan periode. Dalam contoh ini dengan perancis lokal, koma ditangani dengan benar sebagai tanda desimal:
>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222
Metode lokal.atoi
juga tersedia, tapi argumen harus berupa integer.
Jika anda tidak't menolak untuk modul pihak ketiga, anda bisa check out fastnumbers modul. Ini menyediakan fungsi yang disebut fast_real yang tidak persis apa pertanyaan ini meminta dan tidak lebih cepat dari murni-Python pelaksanaan:
>>> from fastnumbers import fast_real
>>> fast_real("545.2222")
545.2222
>>> type(fast_real("545.2222"))
float
>>> fast_real("31")
31
>>> type(fast_real("31"))
int
Pengguna codelogic dan harley benar, tapi perlu diingat jika anda tahu string integer (misalnya, 545) anda dapat memanggil int("545") tanpa terlebih dahulu casting untuk mengapung.
Jika anda string dalam daftar, anda bisa menggunakan fungsi peta juga.
>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
Hal ini hanya baik jika mereka're semua jenis yang sama.
Pertanyaannya tampaknya sedikit lama. Tapi saya sarankan fungsi, parseStr, yang membuat sesuatu yang serupa, yaitu, kembali integer atau float dan jika diberikan ASCII string tidak dapat diubah untuk tidak satupun dari mereka yang kembali itu tak tersentuh. Kode saja mungkin disesuaikan untuk hanya melakukan apa yang anda inginkan:
>>> import string
>>> parseStr = lambda x: x.isalpha() and x or x.isdigit() and \
... int(x) or x.isalnum() and x or \
... len(set(string.punctuation).intersection(x)) == 1 and \
... x.count('.') == 1 and float(x) or x
>>> parseStr('123')
123
>>> parseStr('123.3')
123.3
>>> parseStr('3HC1')
'3HC1'
>>> parseStr('12.e5')
1200000.0
>>> parseStr('12$5')
'12$5'
>>> parseStr('12.2.2')
'12.2.2'
Di Python, bagaimana saya bisa mengurai string numerik seperti "545.2222" yang sesuai float nilai, 542.2222? Atau mengurai string "31" untuk integer, 31? Aku hanya ingin tahu bagaimana untuk mengurai sebuah pecahan string ke float, dan (terpisah) int string ke int.
It's baik bahwa anda meminta untuk melakukan ini secara terpisah. Jika anda're pencampuran mereka, anda dapat menetapkan diri untuk masalah di kemudian hari. Jawaban yang sederhana adalah:
"545.2222"
untuk float:
>>> float("545.2222")
545.2222
"31"
untuk bilangan bulat:
>>> int("31")
31
Konversi dari berbagai basis, dan anda harus tahu dasar di muka (10 adalah default). Catatan anda dapat prefix mereka dengan apa yang Python mengharapkan untuk literal (lihat di bawah) atau menghapus awalan:
>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31
Jika anda don't tahu dasar terlebih dahulu, tapi kau tahu mereka akan memiliki prefiks yang benar, Python dapat menyimpulkan ini untuk anda jika anda melewati 0
sebagai dasar:
>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31
Jika motivasi anda adalah untuk memiliki kode anda sendiri jelas mewakili keras-kode nilai-nilai tertentu, namun, anda mungkin tidak perlu untuk mengkonversi dari dasar - anda dapat membiarkan Python melakukannya untuk anda secara otomatis dengan sintaks yang benar.
Anda dapat menggunakan berhubung awalan untuk mendapatkan konversi otomatis ke bilangan bulat dengan berikut literal. Ini berlaku untuk Python 2 dan 3:
Biner, awalan 0b
>>> 0b11111
31
Oktal, awalan 0o
>>> 0o37
31
Heksadesimal, awalan 0x
>>> 0x1f
31
Hal ini dapat berguna ketika menggambarkan biner bendera, file permissions dalam kode, atau nilai-nilai hex untuk warna - misalnya, tidak ada catatan kutipan:
>>> 0b10101 # binary flags
21
>>> 0o755 # read, write, execute perms for owner, read & ex for group & others
493
>>> 0xffffff # the color, white, max values for red, green, and blue
16777215
Jika anda melihat sebuah integer yang dimulai dari 0, di Python 2, ini adalah (usang) oktal sintaks.
>>> 037
31
Itu adalah buruk karena sepertinya nilai yang harus 37
. Jadi di Python 3, sekarang menimbulkan SyntaxError
:
>>> 037
File "<stdin>", line 1
037
^
SyntaxError: invalid token
Mengkonversi Python 2 octals untuk octals yang bekerja di kedua 2 dan 3 dengan 0o
awalan:
>>> 0o37
31
Yang NAMA parser dapat membantu anda mencari tahu apa tipe data string adalah. Gunakan yaml.beban()
, dan kemudian anda dapat menggunakan jenis(hasil)
untuk menguji untuk jenis:
>>> import yaml
>>> a = "545.2222"
>>> result = yaml.load(a)
>>> result
545.22220000000004
>>> type(result)
<type 'float'>
>>> b = "31"
>>> result = yaml.load(b)
>>> result
31
>>> type(result)
<type 'int'>
>>> c = "HI"
>>> result = yaml.load(c)
>>> result
'HI'
>>> type(result)
<type 'str'>
Saya menggunakan fungsi ini untuk yang
import ast
def parse_str(s):
try:
return ast.literal_eval(str(s))
except:
return
Ini akan mengkonversi string ke tipe
value = parse_str('1') # Returns Integer
value = parse_str('1.5') # Returns Float
def num(s): """num(s) num(3),num(3.7)-->3 num('3')-->3, bil('3.7')-->3.7 num('3,700')-->ValueError num('3'),num('a3'),-->ValueError num('3e4') --> 30000.0 """ coba: kembali int(s) kecuali ValueError: coba: kembali mengapung(s) kecuali ValueError: meningkatkan ValueError('argumen bukan sebuah string dari nomor')
Anda perlu untuk mengambil ke account pembulatan untuk melakukan ini dengan benar.
I. e. int(5.1) => 5 int(5.6) => 5 -- salah, harus 6 jadi kita lakukan int(5.6 + 0.5) => 6
def convert(n):
try:
return int(n)
except ValueError:
return float(n + 0.5)
Untuk typecast di python menggunakan konstruktor fungsi dari jenis, lewat string (atau nilai apapun yang anda mencoba untuk cor) sebagai parameter.
Misalnya:
>>>float("23.333")
23.333
Di belakang layar, python memanggil benda-benda __mengapung__
metode, yang harus kembali mengapung representasi parameter. Ini sangat kuat, karena anda dapat menentukan sendiri jenis (menggunakan kelas) dengan a __mengapung__
metode sehingga dapat dicor ke mengapung dengan menggunakan pelampung(myobject).
Saya heran tidak ada disebutkan regex karena kadang-kadang string harus siap dan dinormalisasi sebelum casting untuk nomor
import re
def parseNumber(value, as_int=False):
try:
number = float(re.sub('[^.\-\d]', '', value))
if as_int:
return int(number + 0.5)
else:
return number
except ValueError:
return float('nan') # or None if you wish
penggunaan:
parseNumber('13,345')
> 13345.0
parseNumber('- 123 000')
> -123000.0
parseNumber('99999\n')
> 99999.0
dan by the way, sesuatu untuk memverifikasi bahwa anda memiliki sejumlah:
import numbers
def is_number(value):
return isinstance(value, numbers.Number)
# will work with int, float, long, Decimal
Ini adalah versi dikoreksi dari https://stackoverflow.com/a/33017514/5973334
Ini akan mencoba untuk mengurai string dan kembali baik int
atau float
tergantung pada apa yang string yang mewakili.
Mungkin kenaikan parsing pengecualian atau memiliki beberapa perilaku tak terduga.
def get_int_or_float(v):
number_as_float = float(v)
number_as_int = int(number_as_float)
return number_as_int if number_as_float == number_as_int else
number_as_float