3) 문자열 (2)

문자열 포매팅(Formatting)

문자열에서 알아야 할것으로는 또하나, 문자열 포매팅이라는 것이 있다. 이것을 공부하기에 앞서 다음과 같은 문자열을 출력하는 프로그램을 작성했다고 가정해보자.

“현재 온도는 18도입니다.”

하지만 시간이 지나서 20도가 된다면 아래와 같은 문장을 출력하는 프로그램.

“현재 온도는 20도입니다”

이러한 프로그램을 어떻게 만들 수 있는지에 대해서는 생각하지 말고 출력해주는 문자열에만 주목해 보자. 출력된 문자열은 모두 같은데 20이라는 숫자와 18이라는 숫자만이 다르다. 이렇게 문자열 내의 어떤 특정한 값을 변화시키는 것이 필요한 경우가 생기는데 이것을 가능하게 해 주는 것이 바로 문자열 포매팅 기법이다.

문자열 포매팅이란 문자열 내에 어떤 값을 삽입하는 방법이다. 다음의 예들을 따라해 보면서 그 사용법을 알아보자.

예 1) 숫자 바로 대입

>>> "I eat %d apples." % 3
'I eat 3 apples.'

위의 예제 결과 값을 보면 알겠지만 위의 예는 문자열 내에 3이라는 정수값을 삽입하는 방법을 보여준다. 삽입할 3이라는 숫자는 가장 뒤에 “%” 문자 다음에 쓰였다. 그리고 문자열 내에 3이라는 값을 넣고 싶은 자리에 "%d"라는 문자를 넣어주었다. 하지만 꼭 문자열 내에 숫자만 넣으라는 법은 없다. 이번에는 숫자 대신 문자열을 넣어 보자.

예 2)문자열 바로 대입

>>> "I eat %s apples." % "five"
'I eat five apples.'

위와 예에서 보는 것과 같이 문자열 내에 또다른 문자열을 삽입하기 위해서는 앞서 사용했던 %d 가 아닌 %s를 썼음을 알 수 있다. 그렇다면 위와 같은 사실로 독자는 유추할 수 있을 것이다. 숫자를 삽입하게 위해서는 %d를 써야 하고 문자열을 삽입하기 위해서는 %s를 써야 한다는 사실을.

예 3) 숫자 변수로 대입

>>> number = 3
>>> "I eat %d apples." % number
'I eat 3 apples.'

예 1처럼 숫자를 바로 대입하나 예 3처럼 숫자값을 나타내는 변수를 대입하나 같은 결과가 나온다.

그렇다면 문자열 안에 한 개가 아닌 여러개의 값을 삽입하고 싶다면 어떻게 해야 할까?

예 4) 두 개 이상의 값을 치환

>>> number = 10
>>> day = "three"
>>> "I ate %d apples. so I was sick for %s days." % (number, day)
'I ate 10 apples. so I was sick for three days.'

예 4처럼 두 개 이상의 값을 치환하려면 위에서 보듯이 마지막 % 다음에 ( ) 사이에 콤마로 구분하여 변수를 넣어 주어야만 한다.

 

문자열 포맷 코드

예 4는 대입시키는 자료형으로 정수와 문자열을 사용했지만 이 이외에도 다양한 것들을 대입시킬 수 있다. 문자열 포맷 코드로는 다음과 같은 것들이 있다.

코드 설명
%s 문자열 (String)
%c 문자 한개(character)
%d 정수 (Integer)
%f 부동소수 (floating-point)
%o 8진수
%x 16진수
%% Literal % (문자 % 자체)

여기서 재미있는 것은 %s 포맷 코드로 이것은 어떤 형태로든 변환이 가능하다. 무슨 말인지 예를 통해 확인해 보자.

>>> "I have %s apples" % 3
'I have 3 apples'
>>> "rate is %s" % 3.234
'rate is 3.234'

3을 문자열 내에 삽입하려면 문자열 내에 %d가 있어야 하고 3.234를 삽입하려면 문자열 내에 %f가 있어야 하지만 %s를 사용하면 이런 것을 생각하지 않아도 된다. 왜냐하면 %s는 자동으로 % 뒤의 파라미터 값을 문자열로 치환하기 때문이다.

[참고] 포맷팅 연산자 %d와 %를 같이 쓸 때는 %%를

>>> "Error is %d%." % 98

당연히 결과값으로 "Error is 98%."가 출력될 것이라고 예상하겠지만 파이썬은 에러 메시지를 보여준다. 이유는 문자열 포맷코드인 %d 와 % 가 같은 문자열 내에 존재하면 %를 나타내기 위해서는 반드시 %%로 해야 %로 되는 법칙이 있다. 이건 꼭 기억해두어야 한다. 하지만 문자열 내에 %d 같은 포맷팅 연산자가 없으면 %는 홀로 쓰여도 상관이 없다. 따라서 위 예를 제대로 실행될 수 있게 하려면 다음과 같이 해야 한다.

>>> "Error is %d%%." % 98
'Error is 98%.'

 

포맷 코드의 또 다른 기능

위에서 보았듯이 %d, %s등의 포맷코드는 문자열 내에 어떤 값을 삽입하기 위해서 사용됨을 알 수 있었다. 하지만 포맷코드를 숫자와 함께 사용하면 더 유용하게 사용할 수 있다. 다음의 예를 보고 따라해 보도록 하자.

예 1) 정렬과 공백

>>> "%10s" % "hi"
'        hi'
 ^^^^^^^^^^

위의 "%10s"의 의미는 길이가 10개인 문자열 공간에서 오른쪽으로 정렬하고 그 앞의 나머지는 공백으로 남겨 두라는 의미이다.

그렇다면 반대쪽인 왼쪽 정렬은 "%-10s"가 될 것이다. 확인해 보자.

>>> "%-10sjane." % 'hi'
'hi        jane.'
 ^^^^^^^^^^

왼쪽으로 정렬하고 나머지는 공백으로 채웠음을 볼 수 있다.

예 2) 소숫점 표현

>>> "%0.4f" % 3.42134234
'3.4213'

3.42134234를 소수점 4번째까지만 나타내고 싶을 경우에 위와 같이 할 수 있다. 즉 여기서 '.'의 의미는 소수점 포인트를 말하고 그 뒤의 숫자 4는 뒤에 나올 숫자의 개수를 말한다. '.'앞의 숫자는 이전의 예에서와 같이 오른쪽 또는 왼쪽 정렬을 말하는 숫자이다.

>>> "%10.4f" % 3.42134234
'    3.4213'
 ^^^^

위의 예는 3.42134234라는 숫자를 10개의 문자열 공간에 오른쪽으로 정렬하고 소수점은 4번째 자리까지만 표시하게 하는 예를 보여준다. 위의 예와의 차이점은 숫자를 오른쪽으로 정렬했다는 점이다.

문자열 함수

앞서 복소수에서 복소수가 자체적으로 가지고 있는 복소수 관련함수가 있었던 것처럼 문자열 역시 자체적으로 가지고 있는 관련함수들이 몇 개 있다. 그 것들을 사용하기 위해서는 문자열 변수이름 뒤에 '.'을 붙인 다음에 관련함수 이름을 써 주면 된다. 이제 문자열이 자체적으로 가지고 있는 유용한 함수들에 대해서 알아보자.

고급 문자열 포매팅(format)

문자열의 format 함수를 이용하면 좀 더 발전된 스타일로 문자열 포맷을 지정할 수 있다. 위에서 알아본 문자열 포매팅 예제들은 format을 이용하면 다음과 같이 바꿀 수 있다.

숫자 바로 대입

>>> "I eat {0} apples".format(3)
'I eat 3 apples'

"I eat {0} apples" 문자열 중 {0} 부분이 3이라는 숫자로 바뀌었다.

 

문자열 바로 대입

>>> "I eat {0} apples".format("five")
'I eat five apples'

문자열의 {0} 항목이 five라는 문자열로 바뀌었다.

 

숫자 변수로 대입

>>> number = 3
>>> "I eat {0} apples".format(number)
'I eat 3 apples'

문자열의 {0} 항목이 number값으로 바뀌었다.

 

두 개 이상의 값을 치환

>>> number = 10
>>> day = "three"
>>> "I ate {0} apples. so I was sick for {1} days.".format(number, day)
'I ate 10 apples. so I was sick for three days.'

두 개 이상의 값을 치환할 경우 문자열의 {0}{1}과 같은 인덱스 항목들이 format 함수의 입력값들로 순서에 맞게 치환된다. 즉 위 예에서 {0}는 format 함수의 첫번째 입력값인 number로 바뀌었고 {1}은 format 함수의 두번째 입력값인 day로 바뀌었다.

 

이름으로 치환하기

>>> "I ate {number} apples. so I was sick for {day} days.".format(number=10, day=3)
'I ate 10 apples. so I was sick for 3 days.'

위 예에서 보듯이 {0}{1} 과 같은 인덱스 항목 대신 {name} 형태를 이용하는 보다 편리한 방법도 있다. {name} 형태를 사용할 경우에는 format 함수의 입력값에는 반드시 name=value와 같은 형태의 입력값이 있어야만 한다.

위 예는 문자열의 {number}{day}가 format 함수의 입력값인 number=10day=3 값으로 각각 치환되는 것을 보여주고 있다.

 

인덱스와 이름을 혼용해서 치환하기

>>> "I ate {0} apples. so I was sick for {day} days.".format(10, day=3)
'I ate 10 apples. so I was sick for 3 days.'

위와 같이 인덱스와 name=value 두개를 혼용해서 사용하는 것도 가능하다.

 

좌측 정렬

>>> "{0:<10}".format("hi")
'hi        '

:<10 표현식을 이용하면 치환되는 문자열을 좌측으로 정렬하고 문자열의 총 자리수를 10으로 맞출 수 있다.

 

우측 정렬

>>> "{0:>10}".format("hi")
'        hi'

우측 정렬은 < 대신 >을 이용하면 된다. 화살표 방향을 생각하면 어느쪽으로 정렬이 되는지 금방 알 수 있을 것이다.

 

가운데 정렬

>>> "{0:^10}".format("hi")
'    hi    '

^기호를 이용하면 가운데 정렬도 가능하다.

 

공백 채우기

>>> "{0:=^10}".format("hi")
'====hi===='
>>> "{0:!<10}".format("hi")
'hi!!!!!!!!'

정렬 시 공백문자 대신에 지정한 문자값으로 채워넣는 것도 가능하다. 채워넣을 문자값은 정렬문자인 <>^ 바로 앞에 삽입해야 한다. 위 예에서 첫번째 예제는 가운데(^)로 정렬하고 빈공간을 = 문자로 채웠고 두번째 예제는 좌측(<)으로 정렬하고 빈공간을 !문자로 채웠다.

 

소수점 표현

>>> y = 3.42134234
>>> "{0:0.4f}".format(y)
'3.4213'

위 예는 format 함수를 이용하여 소수점을 4자리까지만 표현하는 방법을 보여준다. 이전에 살펴보았던 0.4f의 표현식이 그대로 사용됨을 알 수 있다.

>>> "{0:10.4f}".format(y)
'    3.4213'

위와같이 자리수를 10으로 맞출 수도 있다. 역시 이전에 살펴보았던 10.4f의 표현식이 그대로 사용됨을 알 수 있다.

 

{ 또는 }문자 표현하기

>>> "{{ and }}".format()
'{ and }'

format 함수를 이용하여 문자열 포매팅을 할 경우에 { 나 } 문자를 포매팅 문자가 아닌 문자 그대로 사용하고 싶은 경우에는 위 예처럼 {{와 }}처럼 중괄호(brace) 두개를 연속해서 사용해야 한다.

 

소문자를 대문자로 바꾸기(upper)

>>> a = "hi"
>>> a.upper()
'HI'

upper()함수는 소문자를 대문자로 바꾸어준다. 만약 문자열이 이미 대문자라면 아무런 변화도 일어나지 않을 것이다.

 

문자 갯수 세기(count)

>>> a = "hobby"
>>> a.count('b')
2

문자열 중 문자 ‘b’의 개수를 반환한다.

 

위치 알려주기1(find)

>>> a = "Python is best choice"
>>> a.find('b')
10

문자열 중 문자 'b'가 처음으로 나온 위치를 반환한다. 만약 찾는 문자나 문자열이 존재하지 않는다면 -1을 반환한다.

 

위치 알려주기2(index)

>>> a = "Life is too short"
>>> a.index('t')
8

문자열 중 문자 't'가 처음으로 나온 위치를 반환한다. 만약 찾는 문자나 문자열이 존재하지 않는다면 에러를 발생시킨다. 위의 find함수와 다른 점은 없는 문자를 찾으려고 하면 에러가 발생한다는 점이다.

 

문자열 삽입 (join)

>>> a= ","
>>> a.join('abcd')
'a,b,c,d'

"abcd"라는 문자열의 각각의 문자사이에 변수 a의 값인 ','을 삽입한다.

 

대문자를 소문자로 바꾸기(lower)

>>> a = "HI"
>>> a.lower()
'hi'

대문자를 소문자로 바꾸어준다.

 

왼쪽 공백 지우기 (lstrip)

>>> a = " hi"
>>> a.lstrip()
'hi'

문자열중 가장 왼쪽의 연속된 공백들을 모두 지운다. 여기서 lstrip에서 'l'이 의미하는 것은 left이다.

 

오른쪽 공백 지우기 (rstrip)

>>> a= "hi "
>>> a.rstrip()
'hi'

문자열중 가장 오른쪽의 연속된 공백들을 모두 지운다. 여기서 rstrip에서 'r'이 의미하는 것은 right이다.

 

양쪽 공백 지우기 (strip

>>> a = " hi "
>>> a.strip()
'hi'

양쪽의 연속된 공백을 모두 지운다.

 

문자열 바꾸기 (replace)

>>> a = "Life is too short"
>>> a.replace("Life", "Your leg")
'Your leg is too short'

replace(바뀌게 될 문자열, 바꿀 문자열)처럼 사용해서 문자열 내의 특정한 값을 다른 값으로 치환해 준다.

 

문자열 나누기 (split)

>>> a = "Life is too short"
>>> a.split()
['Life', 'is', 'too', 'short']
>>> a = "a:b:c:d"
>>> a.split(':')
['a', 'b', 'c', 'd']

a.split()처럼 괄호안에 아무런 값도 넣어주지 않으면 공백을 기준으로 문자열을 나누어 준다.

 

만약 a.split(':')처럼 괄호안에 특정한 값이 있을 경우에는 괄호안의 값을 구분자로 해서 문자열을 나누어 준다. 이 나눈 값은 리스트에 하나씩 들어가게 된다. ['Life', 'is', 'too', 'short']나 ['a', 'b', 'c', 'd']는 리스트라는 것인데 조금 후에 자세히 알아볼 것이니 너무 신경쓰지 말도록 하자.

위에서 소개한 문자열 관련 함수들은 문자열 처리에서 매우 사용 빈도가 높은 것들이고 유용한 것들이다. 이 외에도 몇 가지가 더 있지만 자주 사용되는 것들은 아니다.

 

예제를 연습해 봅시다