Câu hỏi Làm thế nào để phân tích một chuỗi thành một float hoặc int trong Python?


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

Tôi chỉ muốn biết cách phân tích cú pháp phao  string đến một floatvà (riêng) int  string đến một int.


1761
2017-12-19 01:52


gốc


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


Các câu trả lời:


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

2087
2017-12-19 01:54



chỉ cần tự hỏi tại sao có '04' cuối cùng? tại sao không đơn giản là '00'? phiên bản python hiện tại của tôi không có '04'. - Mangat Rai Modi
@MangatRaiModi Số dấu chấm động vốn đã không hoàn hảo để đại diện cho số thập phân. Để biết thêm, hãy xem stackoverflow.com/q/21895756/931277 - dokkaebi
tại sao không đơn giản int(a) nhưng int(float(a)) ? - user463035818
int(a) sẽ đưa ra một lỗi rằng chuỗi không phải là một số nguyên hợp lệ: ValueError: invalid literal for int() with base 10: '545.222', nhưng chuyển đổi từ một phao sang một int là một chuyển đổi được hỗ trợ. - David Parks


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

443
2017-12-19 02:31



ngầm trộn phao / ints có thể dẫn đến lỗi tinh vi do có thể mất độ chính xác khi làm việc với phao hoặc kết quả khác nhau cho / toán tử trên float / ints. Tùy thuộc vào ngữ cảnh nó có thể thích hợp hơn để trả về int hoặc float, không phải cả hai. - jfs
@ J.F.Sebastian Bạn hoàn toàn chính xác, nhưng có những lúc bạn muốn đầu vào để quyết định cái nào nó sẽ là. Cho phép đầu vào quyết định cái nào có thể hoạt động tốt với kiểu gõ vịt. - TimothyAWiseman
Bạn có thể làm tổ khác try để ném một ngoại lệ khi nó không chuyển đổi thành nổi. - iBug


Python phương pháp để kiểm tra xem một chuỗi là một phao:

def isfloat(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à: isConvertibleToFloat(value)

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

val                   isfloat(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 ngạc nhiên lớn.


416
2018-01-05 04:15



Vui lòng xem xét đổi tên chức năng của bạn thành convertibleToFloat hoặc một cái gì đó tương tự (tên hiện tại có vẻ khó hiểu, ít nhất là với tôi). - MKPS


Đây là một phương pháp khác xứng đá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ân tích cú pháp 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

104
2018-03-01 04:23



đây là không phải 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 đây 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ó để lại số điện thoại một mình và không cho rằng chúng là các 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
@ 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 của các chữ phức tạp. Nó được cho là một lỗi trong ast.literal_evalvà đã được thảo luận đây. - wim


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

74
2017-12-19 02:32



Nitpick: không hoạt động cho các trường hợp cực đoan như float ("2e-3") - Emile
Lưu ý: hãy cẩn thận khi xử lý số tiền được chuyển thành chuỗi, vì một số quốc gia sử dụng "," làm dấu phân cách thập phân - Ben G
@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ỉ bị hỏng. - jchl
@BenG KHÔNG xử lý tiền như một phao. Đó là yêu cầu cho sự cố. Sử dụng số thập phân để kiếm tiền! (Nhưng nhận xét của bạn về ',' vẫn hợp lệ và quan trọng) - ToolmakerSteve
Đừng quên rằng "không phải là một số" (NaN) và +/- vô cùng cũng là giá trị float hợp lệ. Vì thế float("nan") là một giá trị float hoàn toàn hợp lệ mà câu trả lời ở trên sẽ không bắt được - Ronny Andersson


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

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

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

Tại Hoa Kỳ và Vương quốc Anh, dấu phẩy có thể được sử dụng làm dấu tách hàng nghìn. Trong ví dụ này với ngôn ngữ Mỹ, dấu phẩy được xử lý đúng như một dấu tá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 - Quy ước số Châu Âu

bên trong phần lớn các nước 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 ngôn 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 pháp locale.atoi cũng có sẵn, nhưng đối số phải là số nguyên.


45
2017-07-23 16:00





Người dùng codelogic và harley là đúng, nhưng hãy ghi 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 đúc đầu tiên để nổi.

Nếu các chuỗi của bạn nằm trong 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 đều cùng loại.


22
2017-12-19 02:09





Nếu bạn không phản đối mô-đun bên thứ ba, bạn có thể xem fastnumbers mô-đun. Nó cung cấp một chức năng gọi là fast_real thực hiện chính xác những gì mà câu hỏi này đang yêu cầu và thực hiện nhanh hơn so với việc thực thi tinh khiết-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

21
2017-08-14 03:21





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

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

"545.2222" nổi:

>>> float("545.2222")
545.2222

"31"thành 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 cơ sở trước (10 là mặc định). Lưu ý bạn có thể thêm tiền tố cho chúng với những gì Python mong đợi cho các chữ cái của nó (xem bên dưới) hoặc loại bỏ 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 cơ sở trước, 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 0 làm cơ sở:

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

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

Nếu động cơ của bạn là có mã riêng của bạn đại diện rõ ràng các giá trị cụ thể mã hóa cứng, tuy nhiên, 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 đó với cú pháp chính xác.

Bạn có thể sử dụng tiền tố apropos để chuyển đổi tự động thành 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

Octal, tiền tố 0o

>>> 0o37
31

Tiền tố hệ thập lục phân 0x

>>> 0x1f
31

Điều này có thể hữu ích khi mô tả cờ nhị phân, quyền truy cập 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 được chấp nhận).

>>> 037
31

Nó là xấu bởi vì nó trông giống như giá trị nên 37. Vì vậy, trong Python 3, bây giờ nó tăng SyntaxError:

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

Chuyển đổi 2 octals Python thành octals hoạt động ở cả 2 và 3 với 0o tiếp đầu ngữ:

>>> 0o37
31

17
2017-07-23 13:26





Câu hỏi có vẻ hơi cũ. Nhưng hãy để tôi đề xuất một hàm, parseStr, mà làm cho một cái gì đó tương tự, có 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 ai trong số chúng, nó trả về nó không bị ảnh hưởng. 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'

16
2017-09-28 19:45



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