Làm thế nào để tôi phân tích một chuỗi thành một float hoặc int?


2252

Trong Python, làm cách nào tôi có thể phân tích một chuỗi số giống như "545.2222"giá trị float tương ứng của nó , 545.2222? Hoặc phân tích chuỗi "31"thành một số nguyên , 31?

Tôi chỉ muốn biết làm thế nào để phân tích một float str cho a float, và (riêng) một int str thành an int.


7
Theo nguyên tắc chung, nếu bạn có một đối tượng trong Python và muốn chuyển đổi sang loại đối tượng đó, hãy gọi type(my_object)nó. Kết quả thường có thể được gọi là một hàm để thực hiện chuyển đổi. Ví dụ, type(100)kết quả là int, vì vậy bạn có thể gọi int(my_object)để thử chuyển đổi my_objectthành một số nguyên. Điều này không phải lúc nào cũng hoạt động, nhưng là một "dự đoán đầu tiên" tốt khi mã hóa.
robertlayton

1
int(x) if int(x) == float(x) else float(x)
tcpaiva

Câu trả lời:


2626
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545

8
chỉ tự hỏi tại sao cuối cùng lại có '04'? Tại sao không chỉ đơn giản là '00'? phiên bản trăn hiện tại của tôi không có '04'.
Mangat Rai Modi

54
@MangatRaiModi Số dấu phẩy động vốn không hoàn hảo để biểu diễn số thập phân. Để biết thêm, hãy xem stackoverflow.com/q/21895756/931277
dokkaebi

19
Tại sao không đơn giản int(a)nhưng int(float(a))?
idclev 463035818

24
int(a)sẽ đưa ra một lỗi rằng chuỗi không phải là số nguyên hợp lệ: ValueError: invalid literal for int() with base 10: '545.222'nhưng chuyển đổi từ float sang int là một chuyển đổi được hỗ trợ.
David park

4
Bạn nên xử lý ValueErrornếu bạn muốn an toàn
Joe Bobson

515
def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)

81
trộn phao / ints ngầm có thể dẫn đến các lỗi tinh vi do có thể mất độ chính xác khi làm việc với phao hoặc dẫn đến các kết quả khác nhau cho người /vận hành trên phao / ints. Tùy thuộc vào ngữ cảnh, có thể tốt hơn là trả về int hoặc float, không phải cả hai.
jfs

14
@JFSebastian Bạn hoàn toàn chính xác, nhưng có những lúc bạn muốn đầu vào ra lệnh nó sẽ là cái nào. Để đầu vào ra lệnh mà người ta có thể làm việc độc đáo với gõ vịt.
TimothyAWiseman

4
Bạn có thể lồng một cái khác tryđể ném ngoại lệ khi nó không thể chuyển đổi để nổi.
iBug

2
Thất bại vớis = u'\u0000'
Matt Hancock

1
@iBug Ý kiến ​​hay! Tôi khuyên bạn nên ném ValueErrortương ứng except: P
marcelm

511

Phương thức Python để kiểm tra xem một chuỗi có phải là float hay không:

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

Tên dài hơn và chính xác hơn cho chức năng này có thể là: is_convertible_to_float(value)

Cái gì là và không phải là một float trong Python có thể làm bạn ngạc nhiên:

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

Bạn nghĩ rằng bạn biết những con số là gì? Bạn không tốt như bạn nghĩ! Không bất ngờ lớn.

Đừng sử dụng mã này trên phần mềm quan trọng suốt đời!

Nắm bắt các ngoại lệ theo cách này, giết chết chim hoàng yến và ngấu nghiến ngoại lệ tạo ra một cơ hội nhỏ rằng một chuỗi nổi hợp lệ dưới dạng chuỗi sẽ trả về sai. Các float(...)dòng mã có thể thất bại đối với bất kỳ một ngàn lý do mà không có gì để làm với các nội dung của chuỗi. Nhưng nếu bạn đang viết phần mềm quan trọng trong cuộc sống bằng ngôn ngữ nguyên mẫu gõ vịt như Python, thì bạn đã gặp vấn đề lớn hơn nhiều.


1
Vì vậy, sự thật trở thành 1, đó là tôi được thừa hưởng từ C ++, tôi nghĩ
FindOutIslamNow

6
Tôi đã đăng câu trả lời này vào năm 2014. UTF-8glyph cho một người Trung Quốc 4đã biến đổi qua nhiều năm tùy thuộc vào cách các nhà phát triển stackoverflow thay đổi sơ đồ mã hóa ký tự của họ trên công cụ microsoft của họ. Thật tò mò khi thấy nó lật kèo trong nhiều năm qua khi các kế hoạch chuyển đổi mới khẳng định hệ tư tưởng mới của họ. Nhưng có, bất kỳ UTF-8glyph cho một số phương Đông phương Đông không phải là một float Python. Bazeda.
Eric Leschinski

4
Làm thế nào điều này có thể được nâng cao như vậy, với một ngoại lệ rộng lớn như vậy?
E.Serra

Mọi thứ có khoảng trắng ở giữa không thể được chuyển đổi, như "- 12.3""45 e6"
Simon

1
Điều khoản ngoại trừ này nên được giới hạn trongTypeError, ValueError
wim

131

Đây là một phương pháp khác đáng được đề cập ở đây, ast.literal_eval :

Điều này có thể được sử dụng để đánh giá một cách an toàn các chuỗi chứa các biểu thức Python từ các nguồn không đáng tin cậy mà không cần phải phân tích các giá trị.

Đó là, một 'eval' an toàn

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31

11
đây không phải là một giải pháp tốt cho vấn đề Nó hoạt động tốt trong Python 2, nhưng điều sau xảy ra trong Python 3: python >>> import ast >>> ast.literal_eval('1-800-555-1212') -2566 >>> Để làm rõ lý do tại sao đây là một vấn đề, nếu bạn muốn nó để số điện thoại một mình và không cho rằng chúng là biểu thức toán học, thì cách tiếp cận này không dành cho bạn.
royce3

6
@ royce3 Vâng, đó là một điểm tốt và người dùng nên cẩn thận. Hành vi ban đầu được sửa đổi để giải quyết một số vấn đề với phân tích cú pháp phức tạp. Nó được cho là một lỗi trong ast.literal_eval, và đã được thảo luận ở đây .
wim

79
float(x) if '.' in x else int(x)

21
Lưu ý: hãy cẩn thận khi xử lý số tiền được chuyển dưới dạng chuỗi, vì một số quốc gia sử dụng "," làm dấu tách thập phân
Ben G

127
@Emile: Tôi sẽ không gọi "2e-3" là "trường hợp cực đoan". Câu trả lời này chỉ là hỏng.
jchl

14
@BenG KHÔNG thao túng tiền như một cái phao. Đó là yêu cầu rắc rối. Sử dụng số thập phân cho tiền! (Nhưng nhận xét của bạn về ',' vẫn hợp lệ và quan trọng)
ToolmakerSteve 13/12/13

4
Đừng quên rằng "không phải là số" (NaN) và +/- vô cực cũng là các giá trị float hợp lệ. Vì vậy, float("nan")một giá trị nổi hoàn toàn hợp lệ mà câu trả lời trên hoàn toàn không thể nắm bắt được
Ronny Andersson

2
Dễ dàng bị phá vỡ bởi một địa chỉ IP - 192.168.0.1; hoặc"This is not a good approach. :)"
Todor Minakov

69

Bản địa hóa và dấu phẩy

Bạn nên xem xét khả năng dấu phẩy trong biểu diễn chuỗi của một số, đối với các trường hợp như float("545,545.2222")ném ngoại lệ. Thay vào đó, sử dụng các phương thức localeđể chuyển đổi chuỗi thành số và diễn giải chính xác dấu phẩy. Cáclocale.atof cải phương pháp để một phao trong một bước khi locale đã được đặt ra cho các ước số mong muốn.

Ví dụ 1 - Công ước số Hoa Kỳ

Ở Hoa Kỳ và Vương quốc Anh, dấu phẩy có thể được sử dụng như một dấu phân cách hàng ngàn. Trong ví dụ này với miền địa phương Mỹ, dấu phẩy được xử lý đúng như dấu phân cách:

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

Ví dụ 2 - Công ước số châu Âu

phần lớn các quốc gia trên thế giới , dấu phẩy được sử dụng cho dấu thập phân thay vì dấu chấm. Trong ví dụ này với miền địa phương Pháp, dấu phẩy được xử lý chính xác dưới dạng dấu thập phân:

>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222

Phương thức locale.atoinày cũng có sẵn, nhưng đối số phải là một số nguyên.


Đây có vẻ là một giải pháp lý tưởng khi bạn biết nên trả lại một float hoặc int, nhưng làm thế nào bạn có thể lấy cái này để trả về một int chỉ khi một int được thông qua? Ví dụ, x = '1'; locale.atof(x)trả về 1.0khi tôi thực sự muốn 1.
dùng5359531

Sử dụng phương pháp của Dino, tôi đoán câu trả lời sẽ là sử dụng một cái gì đó như thế này:locale.atof(x) if locale.localeconv().get('decimal_point') in x else locale.atoi(x)
user5359531

Tôi sẽ khuyên bạn nên sử dụng phương pháp của Javier ở trên (gói locale.atoithử và sử dụng locale.atofngoại lệ - có lẽ dễ đọc hơn.
Mark Chackerian

27

Nếu bạn không phản đối các mô-đun của bên thứ ba, bạn có thể kiểm tra mô-đun fastnumbers . Nó cung cấp một hàm gọi là fast_real thực hiện chính xác những gì câu hỏi này yêu cầu và thực hiện nhanh hơn so với triển khai Python thuần túy:

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

24

Người dùng codelogicharley là chính xác, nhưng hãy nhớ nếu bạn biết chuỗi là một số nguyên (ví dụ: 545), bạn có thể gọi int ("545") mà không cần truyền đầu tiên để nổi.

Nếu các chuỗi của bạn nằm trong một danh sách, bạn cũng có thể sử dụng chức năng bản đồ.

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

Nó chỉ tốt nếu tất cả chúng cùng loại.


21

Trong Python, làm cách nào tôi có thể phân tích một chuỗi số như "545.2222" thành giá trị float tương ứng của nó, 542.2222? Hoặc phân tích chuỗi "31" thành một số nguyên, 31? Tôi chỉ muốn biết làm thế nào để phân tích một chuỗi float thành một float và (riêng) một chuỗi int thành một int.

Thật tốt khi bạn yêu cầu làm những việc này một cách riêng biệt. Nếu bạn trộn chúng, bạn có thể tự đặt ra vấn đề sau này. Câu trả lời đơn giản là:

"545.2222" để nổi:

>>> float("545.2222")
545.2222

"31" đến một số nguyên:

>>> int("31")
31

Chuyển đổi khác, ints đến và từ chuỗi và chữ:

Chuyển đổi từ các cơ sở khác nhau và bạn nên biết trước cơ sở (10 là mặc định). Lưu ý rằng bạn có thể đặt tiền tố cho chúng với những gì Python mong đợi cho chữ của nó (xem bên dưới) hoặc xóa tiền tố:

>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31

Nếu bạn không biết trước cơ sở, nhưng bạn biết họ sẽ có tiền tố chính xác, Python có thể suy ra điều này cho bạn nếu bạn vượt qua 0làm cơ sở:

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

Văn học không thập phân (tức là số nguyên) từ các cơ sở khác

Tuy nhiên, nếu động lực của bạn là có mã riêng đại diện rõ ràng cho các giá trị cụ thể được mã hóa cứng, bạn có thể không cần phải chuyển đổi từ các cơ sở - bạn có thể để Python tự động làm điều đó cho bạn với cú pháp chính xác.

Bạn có thể sử dụng tiền tố apropos để nhận chuyển đổi tự động sang số nguyên với các chữ sau . Đây là hợp lệ cho Python 2 và 3:

Nhị phân, tiền tố 0b

>>> 0b11111
31

Tiền tố, tiền tố 0o

>>> 0o37
31

Hệ thập lục phân, tiền tố 0x

>>> 0x1f
31

Điều này có thể hữu ích khi mô tả cờ nhị phân, quyền tệp trong mã hoặc giá trị hex cho màu sắc - ví dụ: lưu ý không có dấu ngoặc kép:

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

Làm cho Python 2 octals mơ hồ tương thích với Python 3

Nếu bạn thấy một số nguyên bắt đầu bằng 0, trong Python 2, đây là cú pháp bát phân (không dùng nữa).

>>> 037
31

Đó là xấu vì có vẻ như giá trị nên được 37. Vì vậy, trong Python 3, nó hiện ra một SyntaxError:

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

Chuyển đổi octals Python 2 của bạn thành octals hoạt động ở cả 2 và 3 với 0otiền tố:

>>> 0o37
31

20

Câu hỏi có vẻ hơi cũ. Nhưng hãy để tôi đề xuất một hàm, parseStr, làm cho một cái gì đó tương tự, nghĩa là trả về số nguyên hoặc float và nếu một chuỗi ASCII đã cho không thể được chuyển đổi thành không có trong số chúng thì nó sẽ trả về nó. Mã của khóa học có thể được điều chỉnh để chỉ làm những gì bạn muốn:

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

8
1e3là một số trong python, nhưng một chuỗi theo mã của bạn.
Cees Timmerman

16

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


1
Điều này sẽ cung cấp cho bạn một đối tượng float nếu chuỗi của bạn là "0" hoặc "0.0", thay vì int nó cung cấp cho các số hợp lệ khác.
Brian

14

Tôi sử dụng chức năng này cho điều đó

import ast

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

Nó sẽ chuyển đổi chuỗi thành loại của nó

value = parse_str('1')  # Returns Integer
value = parse_str('1.5')  # Returns Float

Xin lưu ý rằng parse_str(' 1')(với một khoảng trắng) sẽ trở lại None, không 1.
musiphil

13

Trình phân tích cú pháp YAML có thể giúp bạn tìm ra kiểu dữ liệu nào trong chuỗi của bạn. Sử dụng yaml.load(), và sau đó bạn có thể sử dụng type(result)để kiểm tra loại:

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

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

1
Tại sao bạn sẽ tăng trong exceptphần của bạn nếu bạn không làm gì ở đó? float () sẽ nâng cao cho bạn.
Greg0ry

1
bạn đúng tôi đoán tôi đã sao chép và dán từ một chức năng mà tôi đã đưa ra một ngoại lệ cụ thể. sẽ chỉnh sửa. cảm ơn
Totoro

1
Điều này sẽ cố phân tích một chuỗi và trả về inthoặcfloat tùy thuộc vào những gì chuỗi đại diện. Nó có thể tăng ngoại lệ phân tích cú pháp hoặc [có một số hành vi không mong muốn] [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')

6

Bạn cần phải tính đến làm tròn để làm điều này đúng.

Tức là int (5.1) => 5 int (5.6) => 5 - sai, nên là 6 nên chúng tôi làm int (5.6 + 0.5) => 6

def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)

4
Điểm tốt. Tuy nhiên, điều đó gây ra lạm phát, vì vậy Python 3các ngôn ngữ hiện đại khác sử dụng tính năng làm tròn của ngân hàng.
Cees Timmerman

2
Câu trả lời này là sai (như được viết ban đầu). Nó nhầm intlẫn hai trường hợp và float. Và nó sẽ đưa ra một ngoại lệ, khi nlà một chuỗi, như OP mong muốn. Có thể bạn muốn nói: Khi một intkết quả mong muốn, roundnên thực hiện chuyển đổi SAU để nổi. Nếu hàm LUÔN LUÔN trả về một int, thì bạn không cần phần ngoại trừ - toàn bộ thân hàm có thể int(round(float(input))). Nếu hàm sẽ trả về một int nếu có thể, nếu không thì là float, thì giải pháp ban đầu của javier là chính xác!
ToolmakerSteve 13/12/13

5

Tôi ngạc nhiên không ai đề cập đến regex vì đôi khi chuỗi phải được chuẩn bị và chuẩn hóa trước khi chuyển sang số

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

sử dụng:

parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0

và nhân tiện, một cái gì đó để xác minh bạn có một số:

import numbers
def is_number(value):
    return isinstance(value, numbers.Number)
    # will work with int, float, long, Decimal

5

Để typecast trong python sử dụng các hàm xây dựng của kiểu, truyền chuỗi (hoặc bất kỳ giá trị nào bạn đang cố gắng truyền) làm tham số.

Ví dụ:

>>>float("23.333")
   23.333

Đằng sau hậu trường, trăn đang gọi các đối tượng __float__ phương thức , sẽ trả về một đại diện float của tham số. Điều này đặc biệt mạnh mẽ, vì bạn có thể định nghĩa các kiểu của riêng mình (sử dụng các lớp) bằng một __float__phương thức để nó có thể được chuyển thành float bằng float (myobject).


3

Đây là phiên bản sửa chữa của https://stackoverflow.com/a/33017514/5973334

Điều này sẽ cố phân tích một chuỗi và trả về một trong hai inthoặc floattùy thuộc vào những gì chuỗi đại diện. Nó có thể tăng ngoại lệ phân tích cú pháp hoặc có một số hành vi không mong muốn .

  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

2

Truyền chuỗi của bạn cho hàm này:

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)

Nó sẽ trả về int, float hoặc chuỗi tùy thuộc vào những gì đã được thông qua.

chuỗi đó là một int

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

chuỗi đó là một float

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

chuỗi đó là một chuỗi

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

chuỗi trông giống như một cái phao

print(type(string_to_number("hel.lo")))
<class 'str'>

1

Sử dụng:

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

Đây là cách Pythonic nhất mà tôi có thể nghĩ ra.


Máy phát điện dừng lại sau khi giải thích đầu tiên float. Các try... catchkhối có lẽ nên được bên trong forvòng lặp.
musiphil

1

Xử lý hex, bát phân, nhị phân, thập phân và float

Giải pháp này sẽ xử lý tất cả các quy ước chuỗi cho các số (tất cả những gì tôi biết).

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)

Kết quả trường hợp thử nghiệm này minh họa những gì tôi đang nói về.

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

Đây là bài kiểm tra:

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)

0

Sử dụng:

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

0

Đây là một hàm sẽ chuyển đổi bất kỳ object(không chỉ str) thành inthoặc float, dựa trên nếu chuỗi thực tế được cung cấp trông giống như int hoặc float. Hơn nữa nếu đó là một đối tượng có cả hai __float__int__phương thức, nó mặc định sử dụng__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

-1

Bằng cách sử dụng các phương thức int và float, chúng ta có thể chuyển đổi một chuỗi thành số nguyên và số float.

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

y='67'
print(int(y))

Câu trả lời này không thêm bất cứ điều gì mới. Xem, ví dụ, câu trả lời này cung cấp thông tin tương tự và nhiều hơn nữa.
Georgy

-3

eval()là một giải pháp rất tốt cho câu hỏi này Nó không cần kiểm tra xem số đó là int hay float, nó chỉ cho tương đương. Nếu các phương pháp khác là bắt buộc, hãy thử

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

thử ngoại trừ cũng có thể được sử dụng như là một thay thế. Hãy thử chuyển đổi chuỗi thành int bên trong khối thử. Nếu chuỗi sẽ là một giá trị float, nó sẽ đưa ra một lỗi sẽ bị bắt trong khối ngoại trừ, như thế này

try:
    print(int(string))
except:
    print(float(string))

-10

Đây là một cách giải thích khác cho câu hỏi của bạn (gợi ý: nó mơ hồ). Có thể bạn đang tìm kiếm một cái gì đó như thế này:

def parseIntOrFloat( aString ):
    return eval( aString )

Nó hoạt động như thế này ...

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

Về mặt lý thuyết, có một lỗ hổng tiêm. Chuỗi có thể, ví dụ là "import os; os.abort()". Tuy nhiên, không có bất kỳ nền tảng nào về việc chuỗi đến từ đâu, khả năng là suy đoán lý thuyết. Vì câu hỏi rất mơ hồ, không rõ lỗ hổng này có thực sự tồn tại hay không.


7
Ngay cả khi đầu vào của anh ấy an toàn 100%, eval()thì chậm hơn 3 lần try: int(s) except: float(s).
Cees Timmerman

1
Chà, evalthực tế rất tệ (bạn phải biết vì bạn có danh tiếng 310k)
U10-Chuyển tiếp
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.