Bagaimana cara mengurai string ke float atau int?

2252

Dengan Python, bagaimana saya bisa mengurai string numerik seperti "545.2222"nilai float yang sesuai 545.2222,? Atau parsing string "31"ke integer 31,?

Saya hanya ingin tahu cara mengurai float str ke float, dan (secara terpisah) int str ke int.

Tristan Havelick
sumber
7
Sebagai aturan umum, jika Anda memiliki objek dengan Python, dan ingin mengonversi ke tipe objek itu, panggil type(my_object)saja. Hasilnya biasanya dapat disebut sebagai fungsi untuk melakukan konversi. Misalnya type(100)hasil dalam int, jadi Anda dapat menelepon int(my_object)untuk mencoba mengonversi my_objectke bilangan bulat. Ini tidak selalu berhasil, tetapi merupakan "tebakan pertama" yang bagus saat coding.
robertlayton
1
int(x) if int(x) == float(x) else float(x)
tcpaiva

Jawaban:

2627
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
Harley Holcombe
sumber
8
hanya ingin tahu mengapa ada '04' pada akhirnya? mengapa tidak sekadar '00'? juga versi python saya saat ini tidak memiliki '04'.
Mangat Rai Modi
54
@MangatRaiModi Nomor titik apung secara inheren tidak sempurna untuk mewakili desimal. Untuk lebih lanjut, lihat stackoverflow.com/q/21895756/931277
dokkaebi
19
mengapa tidak hanya int(a)tetapi int(float(a))?
idclev 463035818
24
int(a)akan memberikan kesalahan bahwa string tersebut bukan bilangan bulat yang valid:, ValueError: invalid literal for int() with base 10: '545.222'tetapi mengonversi dari float ke int adalah konversi yang didukung.
David Parks
4
Anda harus menangani ValueErrorjika Anda ingin aman
Joe Bobson
515
def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)
Javier
sumber
81
float / ints pencampuran implisit dapat menyebabkan bug halus karena kemungkinan kehilangan presisi saat bekerja dengan float atau hasil yang berbeda untuk /operator di float / int. Tergantung pada konteksnya, mungkin lebih baik mengembalikan int atau float, bukan keduanya.
jfs
14
@ JFSebastian Anda sepenuhnya benar, tetapi ada kalanya Anda ingin input menentukan yang mana yang akan dimasukkan. Membiarkan input menentukan yang mana yang dapat bekerja dengan baik dengan mengetik-bebek.
TimothyAWiseman
4
Anda bisa membuat sarang yang lain tryuntuk melempar pengecualian ketika itu tidak dapat dikonversi menjadi float.
iBug
2
Gagal dengans = u'\u0000'
Matt Hancock
1
@ iBug Ide bagus! Saya sarankan ValueErroruntuk memasukkan yang sesuai except: P
marcelm
511

Metode Python untuk memeriksa apakah string adalah float:

def is_float(value):
  try:
    float(value)
    return True
  except:
    return False

Nama yang lebih panjang dan lebih akurat untuk fungsi ini adalah: is_convertible_to_float(value)

Apa itu, dan bukan float di Python mungkin mengejutkan Anda:

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 nomor apa itu? Anda tidak sebagus yang Anda kira! Bukan kejutan besar.

Jangan gunakan kode ini pada perangkat lunak yang kritis!

Menangkap pengecualian luas dengan cara ini, membunuh kenari dan melahap pengecualian menciptakan peluang kecil bahwa pelampung yang valid sebagai string akan kembali palsu. The float(...)baris kode dapat gagal untuk setiap seribu alasan yang tidak ada hubungannya dengan isi string. Tetapi jika Anda menulis perangkat lunak penting dalam bahasa prototipe mengetik bebek seperti Python, maka Anda memiliki masalah yang jauh lebih besar.

Eric Leschinski
sumber
1
Jadi benar menjadi 1, yaitu saya warisi dari C ++ saya pikir
FindOutIslamNow
6
Saya memposting jawaban ini pada tahun 2014. UTF-8Mesin terbang untuk China 4telah berubah selama bertahun-tahun tergantung pada bagaimana pengembang stackoverflow mengubah skema pengkodean karakter mereka pada toolstack microsoft mereka. Sangat penasaran melihatnya membalik selama bertahun-tahun ketika skema konversi baru menegaskan ideologi baru mereka. Tapi ya, UTF-8Mesin terbang apa pun untuk numerik oriental Timur bukanlah pelampung Python. Bazinga.
Eric Leschinski 4-18
4
bagaimana hal ini bisa begitu diputuskan, dengan pengecualian yang luas?
E.Serra
Segala sesuatu dengan ruang di antaranya tidak dapat dikonversi, seperti "- 12.3"dan"45 e6"
Simon
1
Klausa kecuali ini harus dibatasi untukTypeError, ValueError
wim
131

Ini adalah metode lain yang layak disebutkan di sini, ast.literal_eval :

Ini dapat digunakan untuk mengevaluasi string yang berisi ekspresi Python dari sumber yang tidak dipercaya dengan aman tanpa harus menguraikan nilai-nilai itu sendiri.

Artinya, 'eval' yang aman

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
wim
sumber
11
ini bukan solusi yang baik untuk masalah ini. Ini berfungsi dengan baik di Python 2, tetapi berikut ini terjadi di Python 3: python >>> import ast >>> ast.literal_eval('1-800-555-1212') -2566 >>> Untuk memperjelas mengapa ini menjadi masalah, jika Anda ingin meninggalkan nomor telepon sendiri dan tidak menganggap mereka adalah ekspresi matematis, maka pendekatan ini bukan untuk Anda.
royce3
6
@ royce3 Ya, itu poin bagus dan pengguna harus berhati-hati. Perilaku awalnya diubah untuk mengatasi beberapa masalah dengan penguraian literal kompleks. Ini bisa dibilang sebuah bug ast.literal_eval, dan telah dibahas di sini .
wim
79
float(x) if '.' in x else int(x)
Dino Viehland
sumber
21
Catatan: hati-hati ketika berhadapan dengan jumlah uang yang diteruskan sebagai string, karena beberapa negara menggunakan "," sebagai pemisah desimal
Ben G
127
@ Emile: Saya tidak akan menyebut "2e-3" sebuah "kasus ekstrim". Jawaban ini rusak.
jchl
14
@BenG JANGAN memanipulasi uang sebagai pelampung. Itu meminta masalah. Gunakan desimal untuk uang! (Tetapi komentar Anda tentang ',' masih valid dan penting)
ToolmakerSteve
4
Jangan lupa bahwa "bukan angka" (NaN) dan +/- tak terhingga juga merupakan nilai float yang valid. Begitu float("nan")juga dengan nilai float yang valid sehingga jawaban di atas tidak akan menangkap sama sekali
Ronny Andersson
2
Mudah dirusak oleh alamat IP - 192.168.0.1; atau"This is not a good approach. :)"
Todor Minakov
69

Lokalisasi dan koma

Anda harus mempertimbangkan kemungkinan koma dalam representasi string angka, untuk kasus seperti float("545,545.2222")yang melempar pengecualian. Alih-alih, gunakan metode localeuntuk mengonversi string menjadi angka dan menafsirkan koma dengan benar. The locale.atofMetode bertobat untuk pelampung dalam satu langkah setelah lokal telah ditetapkan untuk konvensi angka yang diinginkan.

Contoh 1 - Konvensi nomor Amerika Serikat

Di Amerika Serikat dan Inggris, koma dapat digunakan sebagai pemisah ribuan. Dalam contoh ini dengan lokal Amerika, koma ditangani dengan benar 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 - konvensi nomor Eropa

Di sebagian besar negara di dunia , koma digunakan untuk tanda desimal alih-alih tanda titik. Dalam contoh ini dengan lokal Prancis, 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 locale.atoiini juga tersedia, tetapi argumen harus berupa bilangan bulat.

Mark Chackerian
sumber
Ini tampak seperti solusi ideal ketika Anda tahu apakah pelampung atau int harus dikembalikan, tetapi bagaimana Anda bisa mendapatkan ini untuk mengembalikan int hanya jika int dilewatkan? Misalnya, x = '1'; locale.atof(x)kembali 1.0ketika saya benar-benar ingin 1.
user5359531
Menggunakan metode Dino, saya kira jawabannya adalah menggunakan sesuatu seperti ini:locale.atof(x) if locale.localeconv().get('decimal_point') in x else locale.atoi(x)
user5359531
Saya akan merekomendasikan menggunakan metode Javier di atas (membungkus locale.atoidalam mencoba dan menggunakan locale.atofpengecualian - itu mungkin lebih mudah dibaca.
Mark Chackerian
27

Jika Anda tidak menolak modul pihak ketiga, Anda bisa melihat modul fastnumber . Ini menyediakan fungsi yang disebut fast_real yang melakukan persis apa yang diminta pertanyaan ini dan melakukannya lebih cepat daripada implementasi murni-Python:

>>> 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
SethMMorton
sumber
24

Pengguna codelogic dan harley benar, tetapi perlu diingat jika Anda tahu string adalah integer (misalnya, 545), Anda dapat memanggil int ("545") tanpa terlebih dahulu melakukan casting untuk mengapung.

Jika string Anda ada dalam daftar, Anda bisa menggunakan fungsi peta juga.

>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>

Itu hanya baik jika mereka semua tipe yang sama.

Peter Mortensen
sumber
21

Dalam Python, bagaimana saya bisa mengurai string numerik seperti "545.2222" ke nilai float yang sesuai, 542.2222? Atau parsing string "31" ke integer, 31? Saya hanya ingin tahu bagaimana mengurai string float ke float, dan (secara terpisah) string int ke int.

Ada baiknya Anda meminta untuk melakukan ini secara terpisah. Jika Anda mencampurnya, Anda mungkin menyiapkan diri untuk masalah nanti. Jawaban sederhananya adalah:

"545.2222" untuk mengapung:

>>> float("545.2222")
545.2222

"31" ke integer:

>>> int("31")
31

Konversi lain, int ke dan dari string dan literal:

Konversi dari berbagai pangkalan, dan Anda harus tahu pangkalan di muka (10 adalah default). Catatan Anda bisa mengawali mereka dengan apa yang Python harapkan untuk literalnya (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 tidak tahu basis sebelumnya, tetapi Anda tahu mereka akan memiliki awalan yang benar, Python dapat menyimpulkan ini untuk Anda jika Anda lulus 0sebagai basis:

>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31

Literal Non-Desimal (yaitu Integer) dari Basa lain

Namun, jika motivasi Anda adalah untuk memiliki kode sendiri dengan jelas mewakili nilai spesifik yang dikodekan secara keras, Anda mungkin tidak perlu mengonversi dari basis - Anda dapat membiarkan Python melakukannya untuk Anda secara otomatis dengan sintaks yang benar.

Anda dapat menggunakan awalan apropos untuk mendapatkan konversi otomatis ke bilangan bulat dengan literal berikut . Ini berlaku untuk Python 2 dan 3:

Biner, awalan 0b

>>> 0b11111
31

Oktal, awalan 0o

>>> 0o37
31

Heksadesimal, awalan 0x

>>> 0x1f
31

Ini dapat berguna saat menggambarkan flag biner, izin file dalam kode, atau nilai hex untuk warna - misalnya, perhatikan tanpa tanda kutip:

>>> 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

Membuat ambigual Python 2 oktal kompatibel dengan Python 3

Jika Anda melihat bilangan bulat yang dimulai dengan 0, dalam Python 2, ini adalah sintaks oktal (tidak digunakan).

>>> 037
31

Itu buruk karena sepertinya nilainya seharusnya 37. Jadi dalam Python 3, sekarang memunculkan SyntaxError:

>>> 037
  File "<stdin>", line 1
    037
      ^
SyntaxError: invalid token

Ubah Python 2 oktal Anda menjadi oktal yang berfungsi di 2 dan 3 dengan 0oawalan:

>>> 0o37
31
Aaron Hall
sumber
20

Pertanyaannya agak lama. Tapi izinkan saya menyarankan fungsi, parseStr, yang membuat sesuatu yang serupa, yaitu, mengembalikan integer atau float dan jika string ASCII yang diberikan tidak dapat dikonversi ke tidak satupun dari mereka mengembalikannya tidak tersentuh. Kode tentu saja dapat 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'
krzym
sumber
8
1e3adalah angka dalam python, tetapi string sesuai dengan kode Anda.
Cees Timmerman
16

float("545.2222") dan int(float("545.2222"))

codelogic
sumber
1
Ini akan memberi Anda objek float jika string Anda adalah "0" atau "0,0", daripada int yang diberikannya untuk angka yang valid lainnya.
Brian
14

Saya menggunakan fungsi ini untuk itu

import ast

def parse_str(s):
   try:
      return ast.literal_eval(str(s))
   except:
      return

Ini akan mengkonversi string ke tipenya

value = parse_str('1')  # Returns Integer
value = parse_str('1.5')  # Returns Float
Shameem
sumber
Harap dicatat bahwa parse_str(' 1')(dengan spasi) akan kembali None, tidak 1.
musiphil
13

The YAML parser dapat membantu Anda mengetahui apa yang datatype string Anda adalah. Gunakan yaml.load(), dan kemudian Anda dapat menggunakan type(result)untuk menguji 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'>
Rafe
sumber
11
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
Totoro
sumber
1
Mengapa Anda membesarkan exceptbagian Anda jika Anda tidak melakukan apa pun di sana? float () akan menaikkan untuk Anda.
Greg0ry
1
Anda benar saya kira saya menyalin dan menempel dari fungsi yang saya buat pengecualian tertentu. akan diedit. terima kasih
Totoro
1
Ini akan mencoba mengurai string dan mengembalikan salah satu intatau floattergantung pada apa yang diwakili string tersebut. Mungkin muncul pengecualian parsing atau [memiliki perilaku yang tidak terduga] [1].
Kuzeko
9
def num(s):
    """num(s)
    num(3),num(3.7)-->3
    num('3')-->3, num('3.7')-->3.7
    num('3,700')-->ValueError
    num('3a'),num('a3'),-->ValueError
    num('3e4') --> 30000.0
    """
    try:
        return int(s)
    except ValueError:
        try:
            return float(s)
        except ValueError:
            raise ValueError('argument is not a string of number')
Jerry T
sumber
6

Anda perlu mempertimbangkan pembulatan akun untuk melakukan ini dengan benar.

Yaitu int (5.1) => 5 int (5.6) => 5 - salah, harus 6 jadi kita melakukan int (5.6 + 0.5) => 6

def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)
Nick
sumber
4
Poin yang bagus. Itu menyebabkan inflasi, jadi, Python 3 dan bahasa modern lainnya menggunakan pembulatan bankir.
Cees Timmerman
2
Jawaban ini salah (seperti aslinya ditulis). Ini mengacaukan dua kasus intdan float. Dan itu akan memberikan pengecualian, kapan nstring, seperti OP yang diinginkan. Mungkin Anda berarti: Ketika sebuah inthasil yang diinginkan, roundharus dilakukan konversi SETELAH mengapung. Jika fungsi SELALU mengembalikan int, maka Anda tidak perlu bagian kecuali - seluruh fungsi bisa int(round(float(input))). Jika fungsinya harus mengembalikan int jika memungkinkan, jika tidak float, maka solusi asli javier benar!
ToolmakerSteve
5

Saya terkejut tidak ada yang menyebutkan regex karena kadang-kadang string harus disiapkan dan dinormalisasi sebelum casting ke 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

pemakaian:

parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0

dan omong-omong, sesuatu untuk memverifikasi Anda memiliki nomor:

import numbers
def is_number(value):
    return isinstance(value, numbers.Number)
    # will work with int, float, long, Decimal
Sławomir Lenart
sumber
5

Untuk typecast dalam python gunakan fungsi konstruktor dari tipe tersebut, meneruskan string (atau nilai apa pun yang Anda coba gunakan) sebagai parameter.

Sebagai contoh:

>>>float("23.333")
   23.333

Di belakang layar, python memanggil __float__metode objek , yang seharusnya mengembalikan representasi parameter. Ini sangat kuat, karena Anda dapat mendefinisikan tipe Anda sendiri (menggunakan kelas) dengan __float__metode sehingga dapat dilemparkan ke float menggunakan float (myobject).

kCODINGeroo
sumber
2

Lewati string Anda ke fungsi ini:

def string_to_number(str):
  if("." in str):
    try:
      res = float(str)
    except:
      res = str  
  elif(str.isdigit()):
    res = int(str)
  else:
    res = str
  return(res)

Ini akan mengembalikan int, float atau string tergantung pada apa yang telah dilewati.

string yang merupakan int

print(type(string_to_number("124")))
<class 'int'>

string yang mengapung

print(type(string_to_number("12.4")))
<class 'float'>

string yang merupakan string

print(type(string_to_number("hello")))
<class 'str'>

string yang terlihat seperti pelampung

print(type(string_to_number("hel.lo")))
<class 'str'>
Berhubung dgn sibernetika
sumber
1

Menggunakan:

def num(s):
    try:
        for each in s:
            yield int(each)
    except ValueError:
        yield float(each)
a = num(["123.55","345","44"])
print a.next()
print a.next()

Ini adalah cara paling Pythonic yang bisa saya lakukan.

SeasonalShot
sumber
Generator berhenti setelah interpretasi pertama float. The try... catchblok mungkin harus berada di dalam forlingkaran.
musiphil
1

Menangani hex, oktal, biner, desimal, dan float

Solusi ini akan menangani semua konvensi string untuk angka (semua yang saya ketahui).

def to_number(n):
    ''' Convert any number representation to a number 
    This covers: float, decimal, hex, and octal numbers.
    '''

    try:
        return int(str(n), 0)
    except:
        try:
            # python 3 doesn't accept "010" as a valid octal.  You must use the
            # '0o' prefix
            return int('0o' + n, 0)
        except:
            return float(n)

Output test case ini menggambarkan apa yang saya bicarakan.

======================== CAPTURED OUTPUT =========================
to_number(3735928559)   = 3735928559 == 3735928559
to_number("0xFEEDFACE") = 4277009102 == 4277009102
to_number("0x0")        =          0 ==          0
to_number(100)          =        100 ==        100
to_number("42")         =         42 ==         42
to_number(8)            =          8 ==          8
to_number("0o20")       =         16 ==         16
to_number("020")        =         16 ==         16
to_number(3.14)         =       3.14 ==       3.14
to_number("2.72")       =       2.72 ==       2.72
to_number("1e3")        =     1000.0 ==       1000
to_number(0.001)        =      0.001 ==      0.001
to_number("0xA")        =         10 ==         10
to_number("012")        =         10 ==         10
to_number("0o12")       =         10 ==         10
to_number("0b01010")    =         10 ==         10
to_number("10")         =         10 ==         10
to_number("10.0")       =       10.0 ==         10
to_number("1e1")        =       10.0 ==         10

Inilah tesnya:

class test_to_number(unittest.TestCase):

    def test_hex(self):
        # All of the following should be converted to an integer
        #
        values = [

                 #          HEX
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (0xDEADBEEF  , 3735928559), # Hex
                ("0xFEEDFACE", 4277009102), # Hex
                ("0x0"       ,          0), # Hex

                 #        Decimals
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (100         ,        100), # Decimal
                ("42"        ,         42), # Decimal
            ]



        values += [
                 #        Octals
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (0o10        ,          8), # Octal
                ("0o20"      ,         16), # Octal
                ("020"       ,         16), # Octal
            ]


        values += [
                 #        Floats
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                (3.14        ,       3.14), # Float
                ("2.72"      ,       2.72), # Float
                ("1e3"       ,       1000), # Float
                (1e-3        ,      0.001), # Float
            ]

        values += [
                 #        All ints
                 # ----------------------
                 # Input     |   Expected
                 # ----------------------
                ("0xA"       ,         10), 
                ("012"       ,         10), 
                ("0o12"      ,         10), 
                ("0b01010"   ,         10), 
                ("10"        ,         10), 
                ("10.0"      ,         10), 
                ("1e1"       ,         10), 
            ]

        for _input, expected in values:
            value = to_number(_input)

            if isinstance(_input, str):
                cmd = 'to_number("{}")'.format(_input)
            else:
                cmd = 'to_number({})'.format(_input)

            print("{:23} = {:10} == {:10}".format(cmd, value, expected))
            self.assertEqual(value, expected)
shrewmouse
sumber
0

Menggunakan:

>>> str_float = "545.2222"
>>> float(str_float)
545.2222
>>> type(_) # Check its type
<type 'float'>

>>> str_int = "31"
>>> int(str_int)
31
>>> type(_) # Check its type
<type 'int'>
Peter Mortensen
sumber
0

Ini adalah fungsi yang akan mengkonversi object(tidak hanya str) menjadi intatau float, berdasarkan apakah string aktual yang disediakan terlihat seperti int atau float. Lebih lanjut jika itu adalah objek yang memiliki keduanya __floatdan __int__metode, itu default untuk digunakan__float__

def conv_to_num(x, num_type='asis'):
    '''Converts an object to a number if possible.
    num_type: int, float, 'asis'
    Defaults to floating point in case of ambiguity.
    '''
    import numbers

    is_num, is_str, is_other = [False]*3

    if isinstance(x, numbers.Number):
        is_num = True
    elif isinstance(x, str):
        is_str = True

    is_other = not any([is_num, is_str])

    if is_num:
        res = x
    elif is_str:
        is_float, is_int, is_char = [False]*3
        try:
            res = float(x)
            if '.' in x:
                is_float = True
            else:
                is_int = True
        except ValueError:
            res = x
            is_char = True

    else:
        if num_type == 'asis':
            funcs = [int, float]
        else:
            funcs = [num_type]

        for func in funcs:
            try:
                res = func(x)
                break
            except TypeError:
                continue
        else:
            res = x
Abhishek Bhatia
sumber
-1

Dengan menggunakan metode int dan float kita dapat mengonversi string menjadi integer dan float.

s="45.8"
print(float(s))

y='67'
print(int(y))
Shekku Joseph
sumber
Jawaban ini tidak menambahkan sesuatu yang baru. Lihat, misalnya, jawaban ini yang memberikan informasi yang sama dan banyak lagi.
Georgy
-3

eval()adalah solusi yang sangat bagus untuk pertanyaan ini. Tidak perlu memeriksa apakah nomornya int atau float, itu hanya memberikan padanan yang sesuai. Jika diperlukan metode lain, coba

if '.' in string:
    print(float(string))
else:
    print(int(string))

coba-kecuali juga bisa dijadikan alternatif. Coba konversi string menjadi int di dalam blok try. Jika string akan menjadi nilai float, itu akan melempar kesalahan yang akan ditangkap di blok kecuali, seperti ini

try:
    print(int(string))
except:
    print(float(string))
Swati Srivastava
sumber
-10

Berikut ini interpretasi lain dari pertanyaan Anda (petunjuk: tidak jelas). Mungkin Anda mencari sesuatu seperti ini:

def parseIntOrFloat( aString ):
    return eval( aString )

Ini berfungsi seperti ini ...

>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545

Secara teoritis, ada kerentanan injeksi. String bisa, misalnya "import os; os.abort()". Namun, tanpa latar belakang dari mana string itu berasal, kemungkinannya adalah spekulasi teoretis. Karena pertanyaannya tidak jelas, sama sekali tidak jelas apakah kerentanan ini benar-benar ada atau tidak.

S.Lott
sumber
7
Bahkan jika inputnya 100% aman, eval()lebih dari 3 kali lebih lambat try: int(s) except: float(s).
Cees Timmerman
1
Ya, evalitu praktik buruk (Anda harus tahu karena Anda memiliki reputasi 310 ribu orang)
U10-Maju