IT/언어

[python] 문자열을 숫자로 변환하는 int()함수가 적용되지 않는 경우와 해결법

개발자 두더지 2023. 1. 3. 21:55
728x90

일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다.

 

 Python 에서는 int()이나 float()를 이용하여 숫자의 문자열을 숫자 데이터(int형이나 float형)으로 변환할 수 있다.

 float()는 실수를 대상하고 있지만, int()은 정수에 한정되어 있으므로, 생각지도 못하게 에러를 마주하게 되는 경우가 있다. 이번 포스팅에서는 이러한 int()을 이용할 때 에러가 되는 경우에 대해서 설명하고자 한다.

 

 

int() 함수의 기본


 int()은 Python의 내장함수로, 아래와 같인 "정수의 문자열"을 인수로 지정하여 int형의 데이터로 변환시켜준다.

>>> int("123")
123
>>> type(int("123"))
<class 'int'>

 참고로 일본어 전각 문자로 입력된 정수 문자열도 아래와 같이 int 데이터로 변환해준다.

>>> int("123")
123

 또한, 정수부분의 앞에 0이나 부호(+, -)가 있어도 올바르게 변환해준다.

>>> int("-0123")
-123

 그러나, 마침표나 쉼표등 불필요한 문자열이 포함하고 있으면 에러가 발생한다. 이번에는 이러한 int()로 문자열을 변환 할 때 자주 에러가 발생하는 케이스도 그에 맞는 해결 방법을 정리해봤다.

 

 

케이스 1 : 소수점의 문자열


 마침표(.)를 포함하는 소수점 수의 문자열을 int()로 변환하고자 하면 다음과 같이 에러가 발생한다.

>>> int("123.45")
Traceback (most recent call last):
  File "", line 1, in 
ValueError: invalid literal for int() with base 10: '123.45'

 이 경우는 내장함수의 float()로 소수점이 있는 문자열을 소수점이 있는 숫자로 변환한 후에 다시 그 변환된 수를 int()로 변환하면 된다. 그러나 실수가 정수가 되므로 소수점 뒷 자리의 숫자를 모두 사라지므로 주의가 필요하다.

>>> int(float("123.45"))
123

 

 

케이스 2 : 천 단위를 표시하기 위한 쉼표(,)가 있는 문자열


 천 단위를 구분하기 위한 컴마가 있는 정수의 문자열을 int()로 변환하고자하면 아래와 같이 에러가 발생한다.

>>> int("123,000,000")
Traceback (most recent call last):
  File "", line 1, in 
ValueError: invalid literal for int() with base 10: '123,000,000'

 이 경우는 아래와 같이 문자열 메소드의 str.replace()를 이용하여 컴마를 지운 후에 int() 함수를 적용하면 된다.

>>> int("123,000,000".replace(",",""))
123000000

 

 

케이스 3 : 단위를 포함하는 문자열


 정수의 문자열에 km나 kg 등의 단위가 붙어 있는 경우, 그대로 int()로 변환하고자하면 에러가 발생한다.

>>> int("2500km")
Traceback (most recent call last):
  File "", line 1, in 
ValueError: invalid literal for int() with base 10: '2500km'

 이 경우는 아래와 같이 문자열의 숫자만 추출하도록 filter()함수 등을 이용한 후 문자열 메소드 str.join()으로 결합한 다음에 int()로 변환하면 해결할 수 있다.

>>> int("".join(filter(str.isdigit, "2500km")))
2500

  filter()의 첫 번째 인수에 문자가 숫자일 때 True를 반환해주는 메소드 str.isdigit()를 지정한다. 이 방법으로 아래와 같이 숫자의 문자만을 획득할 수 있다.

>>> list(filter(str.isdigit, "2500km"))
['2', '5', '0', '0']
>>> "".join(['2', '5', '0', '0'])
'2500'

 

소수점이 있는 경우

"2500.567km"와 같이 단위뿐만 아니라 소수점이 포함되어 있는 경우, 정규표현을 쓰면 편리하다.

>>> import re
>>> int(float(re.findall(r"\d+\.\d+", "2500.567km")[0]))
2500

 표준 모듈인 re 모듈의 findall()를 이용하여 소수점 수를 표현하는 정규표현의 패턴 \d+\.\d+에 매치하는 문자열의 리스트를 획득할 수 있다. 

>>> import re
>>> re.findall(r"\d+\.\d+", "2500.567km")
['2500.567']

 또한, 단위가 알파벳 문자만 있다면 아래와 같이 filter()를 사용하여 다음과 같이 작성할 수 있지만 조금 복잡해진다.

>>> int(float("".join(filter(lambda c: not str.isalpha(c), "2500.567km"))))
2500

 더욱이 "-40.52도"와 같이 부호(+, -)가 붙어 있는 경우 정규표현의 패턴을 다음과 같이 살짝 변경해주면 된다.

>>> import re
>>> int(float(re.findall(r"[-+]?\d+\.\d+", "-40.52度")[0]))
-40

 

 

케이스 4 : 빈 문자열이나 None


 빈 문자열이나 None()을 int()로 변환하고자하면 아래와 같이 에러가 발생하게 된다.

>>> int("")
Traceback (most recent call last):
  File "", line 1, in 
ValueError: invalid literal for int() with base 10: ''
>>> int(None)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

 이 경우는 아래와 같이 or를 이용하여 기본값을 지정한다. 빈문자열이나 None은 bool 연산에서는 False로 취급되므로 or의 두의 0이 int()의 인수로 이용된다.

>>> e = ""
>>> int(e or 0)
0
>>> n = None
>>> int(n or 0)
0

 또한, 기본값은 아래와 같이 임의의 정수로 지정할 수 있다.

>>> n = None
>>> int(n or -1)
-1

참고자료

https://gammasoft.jp/support/python-error-str-convert-to-int/

728x90