Pythonには、数値を表す文字列を数値の対応物(浮動小数点数または整数)に変換するいくつかの方法があります。最適な方法は、予想される入力文字列の形式、エラー処理の必要性、パフォーマンスの考慮事項などの要因によって異なります。この記事では、これらの手法とそのトレードオフについて説明します。
目次
float()
を使用した文字列から浮動小数点数への変換int()
を使用した文字列から整数への変換ast.literal_eval()
を使用した安全な変換- ローカライズとカンマの処理
- 変換方法のパフォーマンス比較
1. float()
を使用した文字列から浮動小数点数への変換
最も簡単な方法は、組み込みのfloat()
関数を使用することです。これは、文字列を浮動小数点数の等価物に解析しようとします。文字列が有効な浮動小数点数の表現ではない場合(例:数値以外の文字を含む場合)、ValueError
が送出されます。
string_number = "3.14159"
float_number = float(string_number)
print(float_number) # 出力: 3.14159
string_number = "10"
float_number = float(string_number)
print(float_number) # 出力: 10.0
try:
invalid_number = float("abc")
except ValueError:
print("浮動小数点数への変換に無効な文字列です") # 出力: 浮動小数点数への変換に無効な文字列です
2. int()
を使用した文字列から整数への変換
同様に、int()
は文字列を整数に変換します。文字列が整数を表していない場合も、ValueError
を送出します。小数部があるとエラーが発生します。
string_number = "10"
int_number = int(string_number)
print(int_number) # 出力: 10
try:
invalid_number = int("3.14")
except ValueError:
print("整数への変換に無効な文字列です") # 出力: 整数への変換に無効な文字列です
try:
invalid_number = int("abc")
except ValueError:
print("整数への変換に無効な文字列です") # 出力: 整数への変換に無効な文字列です
3. ast.literal_eval()
を使用した安全な変換
ast
モジュールのast.literal_eval()
関数は、特に信頼できない入力に対処する場合に、より安全な代替手段を提供します。これは、Pythonの抽象構文木(AST)を使用して文字列を解析し、文字列に埋め込まれた悪意のあるコードの実行を防ぎます。これは、外部データを取り扱う際のセキュリティにとって不可欠です。
import ast
string_number = "3.14159"
float_number = ast.literal_eval(string_number)
print(float_number) # 出力: 3.14159
string_number = "10"
int_number = ast.literal_eval(string_number)
print(int_number) # 出力: 10
try:
unsafe_input = ast.literal_eval("__import__('os').system('rm -rf /')") # これはエラーを送出します
except (ValueError, SyntaxError):
print("ast.literal_evalが不正なコードの実行を防ぎました")
4. ローカライズとカンマの処理
一部のロケールでは、数値にカンマが桁区切りとして使用されます(例:「1,000.50」)。float()
はこれらを直接処理しません。変換前に、カンマをピリオドに置き換える(またはロケールに応じてその逆)ことで文字列を前処理します。locale
モジュールは、ロケール固有のフォーマットに役立ちます。
import locale
locale.setlocale(locale.LC_NUMERIC, 'en_US.UTF-8') # 米国ロケール例
string_number = "1,000.50"
processed_number = string_number.replace(",", "")
float_number = float(processed_number)
print(float_number) # 出力: 1000.5
# '.'を桁区切り、','を小数点として使用するロケールの場合
string_number = "1.000,50"
processed_number = string_number.replace(".", "").replace(",", ".")
float_number = float(processed_number)
print(float_number) #出力: 1000.5
5. 変換方法のパフォーマンス比較
float()
とint()
は一般的に最も高速です。ast.literal_eval()
は、AST解析のオーバーヘッドのために遅くなります。ただし、そのセキュリティ上の利点は、特に信頼できない入力の場合、パフォーマンスの差を上回る場合が多いです。データが信頼できる大規模データセットの場合、パフォーマンスが重要な場合は、float()
とint()
が優先されます。データセットが小さい場合、またはセキュリティが最優先される場合は、ast.literal_eval()
の方が安全な選択肢です。timeit
によるベンチマークは、定量的な比較を提供できます。