Pythonでは、数値文字列"545.2222"
を対応する浮動小数点値のように解析するにはどうすればよい545.2222
ですか?または、文字列"31"
を整数に解析します31
か?
float str
をにfloat
、(個別に)int str
をに解析する方法を知りたいだけですint
。
int(x) if int(x) == float(x) else float(x)
Pythonでは、数値文字列"545.2222"
を対応する浮動小数点値のように解析するにはどうすればよい545.2222
ですか?または、文字列"31"
を整数に解析します31
か?
float str
をにfloat
、(個別に)int str
をに解析する方法を知りたいだけですint
。
int(x) if int(x) == float(x) else float(x)
回答:
>>> 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または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
あなたはあなたが数が何であるか知っていると思いますか?あなたは思っているほど上手ではありません!大きな驚きではありません。
このように広範な例外をキャッチし、カナリアを強制終了して例外を取得すると、有効な浮動小数点数が文字列としてfalseを返す可能性がわずかにあります。float(...)
コードの行は、文字列の内容とは関係のない千点のいずれかの理由で失敗することができます。しかし、Pythonなどのダックタイピングプロトタイプ言語で生命に関わるソフトウェアを作成している場合は、はるかに大きな問題が発生します。
UTF-8
中国語のグリフは、4
stackoverflow開発者がMicrosoftツールスタックで文字エンコーディングスキームをどのように変更するかに応じて、長年にわたって変化しています。新しい変換スキームが新しいイデオロギーを主張するにつれて、それが何年にもわたって変化するのを見るのは好奇心です。しかし、はい、UTF-8
東洋の東洋数値のグリフはPython浮動小数点ではありません。バジンガ。
"- 12.3"
andのように、間にスペースがあるものはすべて変換できません"45 e6"
TypeError, ValueError
これは、ここで言及するに値するもう1つのメソッドである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モジュールをチェックアウトできます。これはfast_realと呼ばれる関数を提供し、この質問が要求することを正確に実行し、pure-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
ユーザーはcodelogicとハーレーは正しいですが、あなたは、文字列が整数であることがわかっている場合に注意してください(例えば、545)あなたはフロートへの最初の鋳造なしのint(「545」)を呼び出すことができます。
文字列がリストにある場合は、map関数も使用できます。
>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>
それらがすべて同じタイプである場合にのみ良いです。
Pythonでは、「545.2222」のような数値文字列を、対応する浮動小数点値542.2222に解析するにはどうすればよいですか?または、文字列「31」を整数31に解析しますか? float文字列をfloatに、そして(個別に)int文字列をintに解析する方法を知りたいだけです。
これらを個別に行うように依頼するのは良いことです。それらを混合している場合は、後で問題が発生する可能性があります。簡単な答えは:
"545.2222"
フローティングする:
>>> float("545.2222")
545.2222
"31"
整数に:
>>> int("31")
31
さまざまなベースからの変換。事前にベースを知っておく必要があります(デフォルトは10です)。Pythonがリテラルに期待するものを前に付けるか(以下を参照)、前置を削除することができます:
>>> 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
Python 2で0で始まる整数が表示される場合、これは(非推奨の)8進構文です。
>>> 037
31
値がそうであるように見えるので、それは悪い37
です。したがって、Python 3では、次のように発生しSyntaxError
ます。
>>> 037
File "<stdin>", line 1
037
^
SyntaxError: invalid token
Python 2の8進数を、0o
接頭辞が2と3の両方で機能する8進数に変換します。
>>> 0o37
31
質問は少し古いようです。しかし、似たようなもの、つまり整数または浮動小数点数を返し、指定されたASCII文字列をそれらのどれにも変換できない場合、そのままの状態で返す関数parseStrを提案させてください。もちろん、コードはあなたが望むことだけをするように調整されるかもしれません:
>>> 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
Pythonの数値ですが、コードに応じた文字列です。
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を返す必要がある場合は、except部分は必要ありません。関数の本体全体をにすることができます。関数が可能であればintを返し、そうでなければfloatを返す場合、ハビエルの元のソリューションは正しいです!int
round
int(round(float(input)))
数値にキャストする前に文字列を準備して正規化する必要がある場合があるため、正規表現について誰も言及していません。
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
Pythonで型キャストするには、型のコンストラクタ関数を使用して、文字列(またはキャストしようとしている値)をパラメータとして渡します。
例えば:
>>>float("23.333")
23.333
舞台裏では、Pythonがオブジェクト__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'>
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)
使用する:
>>> 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'>
これは、提供される実際の文字列が orのように見えるかどうかに基づいて、object
(だけでなくstr
)をint
or 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ブロック内でintに変換してみてください。文字列が浮動小数点値である場合、次のようにエラーがスローされ、exceptブロックでキャッチされます
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
整数に変換してみることができます。これは常に機能するとは限りませんが、コーディングの際の「最初の推測」として適しています。