답변:
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
int(a)
하지 int(float(a))
않습니까?
int(a)
문자열이 유효한 정수가 아니라는 오류가 발생 ValueError: invalid literal for int() with base 10: '545.222'
하지만 float에서 int로 변환하는 것은 지원되는 변환입니다.
ValueError
안전을 원한다면 처리해야 합니다
def num(s):
try:
return int(s)
except ValueError:
return float(s)
/
플로트 / int 에서 연산자에 대해 다른 결과가 발생하여 미묘한 버그가 발생할 수 있습니다 . 문맥에 따라 int 또는 float을 반환하는 것이 바람직 할 수 있습니다.
try
부동으로 변환 할 수없는 경우 예외를 발생시키기 위해 다른 중첩 할 수 있습니다 .
s = u'\u0000'
ValueError
해당하는 except
: P
def is_float(value):
try:
float(value)
return True
except:
return False
이 기능에 대한 더 길고 정확한 이름은 다음과 같습니다. is_convertible_to_float(value)
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
당신은 당신이 어떤 숫자인지 알고 있다고 생각합니까? 당신은 생각만큼 좋지 않습니다! 큰 놀라움이 아닙니다.
이런 식으로 광범위한 예외를 잡아 내고 카나리아를 죽이고 예외를 흔들면 유효한 float가 문자열로 false가 반환 될 가능성이 적습니다. float(...)
코드 라인은 문자열의 내용과는 아무 상관이없는 천 이유로 실패 할 수 있습니다. 그러나 파이썬과 같은 오리 형 프로토 타입 언어로 생명에 중요한 소프트웨어를 작성하는 경우 훨씬 더 큰 문제가 있습니다.
UTF-8
중국어에 대한 그 글리프 4
는 Microsoft 툴 스택에서 문자 인코딩 방식을 변경하는 방법에 따라 수년에 걸쳐 변화 해 왔습니다. 새로운 전환 체계가 새로운 이데올로기를 주장함에 따라 수년에 걸쳐 플립 플롭을 보는 것은 호기심입니다. 그러나 그렇습니다. UTF-8
동양의 동양 숫자에 대한 모든 그림 문자는 Python float가 아닙니다. 바 징가.
"- 12.3"
및"45 e6"
TypeError, ValueError
이것은 ast.literal_eval에서 언급할만한 또 다른 방법입니다 .
값을 직접 구문 분석 할 필요없이 신뢰할 수없는 소스의 Python 표현식을 포함하는 문자열을 안전하게 평가하는 데 사용할 수 있습니다.
즉, 안전한 '평가'
>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
python >>> import ast >>> ast.literal_eval('1-800-555-1212') -2566 >>>
전화 번호 만 남겨두고 수학 표현식이라고 가정하지 않으려면 이것이 왜 문제인지 명확히하기 위해이 접근법은 적합하지 않습니다.
float(x) if '.' in x else int(x)
float("nan")
위의 대답은 전혀 잡을 것이라고 완벽하게 유효한 부동 소수점 값입니다
192.168.0.1
; 또는"This is not a good approach. :)"
float("545,545.2222")
예외를 발생시키는 경우와 같이 숫자의 문자열 표현에서 쉼표의 가능성을 고려해야합니다 . 대신에 메서드를 사용 locale
하여 문자열을 숫자로 변환하고 쉼표를 올바르게 해석하십시오. 그만큼locale.atof
로케일 번에 한 단계 플로트에있어서의 변환은 원하는 수의 규칙 설정되어있다.
예 1-미국 번호 규칙
미국과 영국에서는 쉼표를 천 단위 구분 기호로 사용할 수 있습니다. 미국 로케일의이 예에서 쉼표는 구분 기호로 올바르게 처리됩니다.
>>> 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
>>>
예 2-유럽 번호 규칙
에서 세계의 국가의 대부분의 쉼표 소수점 마크 대신 기간에 사용됩니다. 프랑스어 로케일이있는이 예에서 쉼표는 소수점으로 올바르게 처리됩니다.
>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222
이 방법 locale.atoi
도 사용할 수 있지만 인수는 정수 여야합니다.
x = '1'; locale.atof(x)
반환합니다 . 1.0
1
locale.atof(x) if locale.localeconv().get('decimal_point') in x else locale.atoi(x)
locale.atoi
시도에 싸서 locale.atof
예외적으로 사용 하는 것이 더 읽기
타사 모듈을 사용하지 않으려면 fastnumbers 모듈을 확인하십시오 . 이 질문이 요구하는 것을 정확하게 수행하고 pure-Python 구현보다 빠르게 수행하는 fast_real 이라는 함수를 제공합니다 .
>>> 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
파이썬에서 "545.2222"와 같은 숫자 문자열을 해당 float 값 542.2222로 구문 분석하는 방법은 무엇입니까? 아니면 문자열 "31"을 정수 31로 구문 분석합니까? float 문자열을 float로 구문 분석하고 int 문자열을 int로 분리하는 방법을 알고 싶습니다.
이 작업을 별도로 수행하는 것이 좋습니다. 혼합하면 나중에 문제가 생길 수 있습니다. 간단한 대답은 다음과 같습니다.
"545.2222"
부유하다 :
>>> float("545.2222")
545.2222
"31"
정수로 :
>>> int("31")
31
다양한 기지에서 변환, 그리고 당신은 미리 기지를 알고 있어야합니다 (10이 기본값). 파이썬이 리터럴에 대해 기대하는 것을 접두사로 붙이거나 (아래 참조) 접두사를 제거 할 수 있습니다.
>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31
사전에 기초를 모르지만 정확한 접두사가 있다는 것을 알고 있다면 0
, 기초로 전달하면 Python이 이것을 대신 할 수 있습니다 .
>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31
그러나 자신의 코드가 하드 코딩 된 특정 값을 명확하게 나타내도록 동기를 부여하는 경우 기본에서 변환 할 필요가 없습니다. 올바른 구문으로 Python에서 자동으로 수행하도록 할 수 있습니다.
apropos 접두사를 사용 하여 다음 리터럴을 사용 하여 정수로 자동 변환 할 수 있습니다 . 이것들은 Python 2와 3에 유효합니다.
이진, 접두사 0b
>>> 0b11111
31
8 진, 접두사 0o
>>> 0o37
31
16 진, 접두사 0x
>>> 0x1f
31
이진 플래그, 코드의 파일 권한 또는 색상의 16 진수 값을 설명 할 때 유용합니다 (예 : 따옴표 없음).
>>> 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
파이썬 2에서 0으로 시작하는 정수가 보이면 이것은 (더 이상 사용되지 않는) 8 진 구문입니다.
>>> 037
31
값이와 같아서 좋지 않습니다 37
. 파이썬 3에서는 이제 SyntaxError
:
>>> 037
File "<stdin>", line 1
037
^
SyntaxError: invalid token
Python 2 8 진수를 0o
접두사를 사용하여 2와 3 모두에서 작동하는 8 진수로 변환하십시오 .
>>> 0o37
31
문제는 조금 오래된 것 같습니다. 그러나 parseStr 함수를 제안합니다.이 함수는 비슷한 것을 만듭니다. 즉 정수 또는 부동 소수점을 반환하고 주어진 ASCII 문자열을 그중 하나로 변환 할 수 없으면 그대로 유지합니다. 물론 코드는 원하는 것만 수행하도록 조정할 수 있습니다.
>>> 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'
1e3
파이썬에서 숫자이지만 코드에 따라 문자열입니다.
YAML의 파서는 데이터 타입 당신의 문자열이 무엇인지 알아내는 데 도움이 될 수 있습니다. 를 사용 yaml.load()
하면 type(result)
유형을 테스트 하는 데 사용할 수 있습니다 .
>>> 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'>
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
except
아무것도하지 않는다면 왜 섹션 을 올리 겠습니까? float ()가 당신을 위해 올릴 것입니다.
int
또는 반환하는 것을 시도합니다 float
. 구문 분석 예외가 발생하거나 [예기치 않은 동작이 발생 함] [1].
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')
이 작업을 올바르게 수행하려면 반올림을 고려해야합니다.
즉 int (5.1) => 5 int (5.6) => 5-잘못되었습니다 .6이어야하므로 int (5.6 + 0.5) => 6
def convert(n):
try:
return int(n)
except ValueError:
return float(n + 0.5)
int
와 float
. 그리고 n
OP가 원하는대로 문자열이 있을 때 예외가 발생 합니다. 어쩌면 당신은 의미 : 때int
결과를 원하는, round
떠 완료를 AFTER 변환해야합니다. 함수가 항상 int를 반환 해야하는 경우 제외 부분이 필요하지 않습니다. 전체 함수 본문이 될 수 있습니다 int(round(float(input)))
. 함수가 가능하면 int를 반환해야하고 그렇지 않으면 float을 반환하면 Javier의 원래 솔루션이 정확합니다!
때로는 문자열을 숫자로 캐스팅하기 전에 준비하고 정규화해야하기 때문에 정규 표현식에 대해 언급 한 사람이 아무도 없습니다.
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
용법:
parseNumber('13,345')
> 13345.0
parseNumber('- 123 000')
> -123000.0
parseNumber('99999\n')
> 99999.0
그건 그렇고, 당신이 숫자를 가지고 있는지 확인하는 것 :
import numbers
def is_number(value):
return isinstance(value, numbers.Number)
# will work with int, float, long, Decimal
파이썬에서 타입 캐스트하려면 문자열 (또는 캐스팅하려는 값)을 매개 변수로 전달하여 유형의 생성자 기능을 사용하십시오.
예를 들면 다음과 같습니다.
>>>float("23.333")
23.333
이면에서 파이썬은 객체 __float__
메소드를 호출 하고 매개 변수의 float 표현을 반환해야합니다. __float__
float (myobject)를 사용하여 float로 캐스트 할 수 있도록 메소드로 클래스를 사용하여 자신의 유형을 정의 할 수 있으므로 특히 강력합니다 .
이것은 https://stackoverflow.com/a/33017514/5973334 의 수정 된 버전 입니다.
이것은 문자열을 구문 분석 하고 문자열이 나타내는 것에 따라 int
또는 반환하는 것을 시도합니다 float
. 구문 분석 예외가 발생하거나 예기치 않은 동작이 발생할 수 있습니다 .
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
이 함수에 문자열을 전달하십시오.
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)
전달 된 내용에 따라 int, float 또는 string을 반환합니다.
int 인 문자열
print(type(string_to_number("124")))
<class 'int'>
부동 문자열
print(type(string_to_number("12.4")))
<class 'float'>
문자열 인 문자열
print(type(string_to_number("hello")))
<class 'str'>
플로트처럼 보이는 문자열
print(type(string_to_number("hel.lo")))
<class 'str'>
사용하다:
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()
이것은 내가 생각해 낼 수있는 가장 파이썬적인 방법입니다.
float
. try
... catch
블록은 아마 내부에 있어야한다 for
루프.
16 진수, 8 진수, 2 진수, 10 진수 및 부동 소수점 처리
이 솔루션은 숫자에 대한 모든 문자열 규칙 (내가 아는 모든 것)을 처리합니다.
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)
이 테스트 사례 출력은 내가 말하는 것을 보여줍니다.
======================== 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
테스트는 다음과 같습니다.
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)
이 함수는 제공된 실제 문자열 이 또는 처럼 보이는지 여부에 따라 object
(뿐만 아니라 str
) int
또는 로 변환하는 함수입니다 . 또한 메소드 와 메소드 가 모두있는 객체 인 경우 기본값은float
int
float
__float
__int__
__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
eval()
이 질문에 대한 아주 좋은 해결책입니다. 숫자가 int인지 float인지 확인할 필요가 없으며 해당하는 숫자 만 제공합니다. 다른 방법이 필요한 경우 시도하십시오
if '.' in string:
print(float(string))
else:
print(int(string))
try-except를 대안으로 사용할 수도 있습니다. try 블록 내에서 string을 int로 변환하십시오. 문자열이 부동 소수점 값이면 예외 블록에서 다음과 같이 오류가 발생합니다.
try:
print(int(string))
except:
print(float(string))
다음은 귀하의 질문에 대한 또 다른 해석입니다 (힌트 : 모호합니다). 다음과 같은 것을 찾고있을 수 있습니다.
def parseIntOrFloat( aString ):
return eval( aString )
이렇게 작동합니다 ...
>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545
이론적으로는 주입 취약점이 있습니다. 문자열은 예를 들어입니다 "import os; os.abort()"
. 그러나 현이 어디에서 왔는지에 대한 배경 지식이 없다면 이론적 추측이 가능합니다. 질문이 모호하기 때문에이 취약점이 실제로 존재하는지 여부는 확실하지 않습니다.
eval()
3 배 이상 느립니다 try: int(s) except: float(s)
.
eval
나쁜 습관입니다 (310k 평판을 가지고 있기 때문에 알아야합니다)
type(my_object)
하십시오. 결과는 일반적으로 변환을 수행하는 함수로 호출 될 수 있습니다. 예를 들어type(100)
결과가int
되므로 호출 하여 정수int(my_object)
로 변환my_object
해 볼 수 있습니다 . 항상 작동하지는 않지만 코딩 할 때 "최초의 추측"입니다.