[Python] '123abc'와 같은 문자열에서 숫자만 빼오는 가장 간단한 방법 Develop Tip

제목 그대로 입니다.

s = '123abc' 와 같은 문자열이 있습니다. (숫자와 문자 사이에 공백이 없습니다)

여기에서 숫자 부분만 뽑아 int 형으로 저장할 수 있는 
방법에는 여러가지가 있습니다.

1) 정규식 이용

import re
s = '123abc'
i = int(re.findall('\d+', s)[0])

와 같이 할 수 있습니다.


2) 필터 이용

다음과 같이 한줄로만 가능합니다.

i = int(filter(str.isdigit,s))

우선 filter 라는 빌트인 함수는
filter(필터함수, 시퀀셜객체) 의 역할은 시퀀셜 객체를 돌면서 필터함수의 패러미터로 넘겨 결과가
True인 것만 동일 시퀀셜 객체로 리턴합니다.
만약 필터함수가 None이면 시퀀셜 객체 중 True인 것만 리턴합니다.

예를 들어

f = filter(None,(1,False,3))
라고 하면 f는 (1,3) 을 가지게 됩니다.

따라서 filter(str.isdigit, s) 의 결과는 '123' 이라는 숫자로만 구성된 문자열이 나오게 됩니다.
이를 int로 형변환 시킨 것이구요.


3) 정규식과 필터로 구현된 것의 시간 차이

위의 1과 2에 구현된 것의 시간차이를 살펴보았습니다.

import re
import datetime

loop = 1000000
s = '123abc'

sdt = datetime.datetime.now()
for _ in xrange(loop):
i = int(re.findall('\d+', s)[0])
edt = datetime.datetime.now()
print "RE <%s>=>%d: loop[%d] extract digits takes %s" % (s, i, loop, edt-sdt)

sdt = datetime.datetime.now()
for _ in xrange(loop):
i = int(filter(str.isdigit,s))
edt = datetime.datetime.now()
print "FT <%s>=>%d: loop[%d] extract digits takes %s" % (s, i, loop, edt-sdt)


위의 결과는

RE <123abc>=>123: loop[1000000] extract digits takes 0:00:01.848112
FT <123abc>=>123: loop[1000000] extract digits takes 0:00:01.236772

가 나왔습니다.

정규식이 약 1.5배 시간을 더 잡아먹고 있음을 알 수 있습니다.


어느 분께는 도움이 되셨기를...

덧글

  • Py3 2017/01/25 11:48 # 삭제 답글

    좋은 정보 알아갑니다! 감사합니다~!
  • 지훈현서아빠 2017/01/25 16:03 #

    도움이 되셨다니 저의 보람입니다~
  • python 2018/01/02 21:28 # 삭제 답글

    감사합니다. 그런데 질문이 하나있습니다. 만약에 -가 포함된 값을 불러오고 싶을 땐 어떻게 하죠?
  • 지훈현서아빠 2018/01/03 09:55 #

    정규식으로 표현하자면,
    'd+' 대신
    '-?d+' 가 되지 않을까 싶네요..

    도움이 되셨기를 바랍니다.
  • python 2018/01/03 11:08 # 삭제 답글

    너무 감사합니다. 새해 복 많이 받으세요~!
  • 지훈현서아빠 2018/01/03 13:39 #

    넵! 저도 감사합니다. 새해 복 많이 받으셔요~
  • pypy 2019/03/01 23:22 # 삭제 답글

    많은도움이 되었습니다.
    혹시 문자만 있는 경우에는 에러처리를 어떻게 해야할까요??
  • 초보 2020/05/28 12:40 # 삭제 답글

    이제 막 프로그래밍을 배우는 학생인데 궁금한 점이 있습니다.
    filter 의 조건에 str.isdigit을 넣으셨는데 str.isdigit()이라는 형태가 특이해서요
    보통 메소드를 사용할 때 객체.메소드 이런 식으로 사용하는 것은 알겠는데
    str.isdigit은 함수.메소드 의 형태가 아닌가요? (제가 모르는 또 다른 함수 형테인가요?)
    이런 형태가 자주 쓰이는지 다른 예도 있는지 궁금합니다.
  • 지훈현서아빠 2020/05/28 14:47 #

    filter 함수는 map 등의 함수와 마찬가지로 첫번째 인자가 값이 아니고 함수개체 입니다.
    즉 패러미터로 넘기는 함수에다가 두번째 이상의 인자를 넣어 무언가를 반복하는 개념입니다.
    도움이 되셨기를 바랍니다.
  • 초보 2020/05/28 18:09 # 삭제 답글

    답변 감사합니다
    그런데 제 질문은 filter 첫번째 인자에 왜 값이 안나왔는지가 아니라 첫번째 인자로 들어간 함수의 형태에 대한 질문인데요
    함수.메소드(ex. str.isdigit)와 같은 형태가 생소해서요.

    메소드도 함수인데 함수+함수가 된 형태인데 코딩할때 흔하게 쓰는 형태인가요?
    이런 형태를 쓰는 또 다른 예가 있는지 궁금해서 질문 남겼습니다.
    감사합니다
  • 지훈현서아빠 2020/05/28 21:26 #

    일반적인 사용형태가 맞습니다. ^^
댓글 입력 영역

구글애드텍스트