본문 바로가기
요약정리/하우투파이썬

str: format(), format_map(), translate()

by JustDoIT 2020. 3. 23.

format()     format_map()     translate()    


 

문자열 포맷을 지정하는 메서드와 문자열을 변환하는 메서드

 

출처: 픽사베이

 

여기서는 문자열의 포맷을 지정할 수 있는 다음 두 메서드와 문자열을 변환하는 메서드를 소개합니다. 다만, 활용할 수 있는 범위가 넓기 때문에 기본적인 쓰임새만 살펴보겠습니다.

 

format(), format_map()

translate()

 

format()

format()은 문자열의 포맷을 지정하는 메서드입니다. 파이썬에서 문자열의 포맷을 지정할 수 있는 방법에는 세 가지가 있습니다. 그 중 문자열 삽입string interpolation에 대해서는 아래 글을 참고하세요.

 

2020/03/12 - [PYTHON/하우투] - f 문자열(feat. 근삿값)

 

일종의 자리 맡기 기호인 중괄호에 따로 인덱스를 지정하지 않으면 순서대로 format()의 인자가 대입됩니다.

 

>>> "Hello, {}! You look {}.".format('Bob', 'good')
'Hello, Bob! You look good.'

>>> "You look {1}, {0}!".format('Bob', 'good')
'You look good, Bob!'
# {0}은 'Bob'을 가리키고, {1}은 'good'을 가리킵니다.

 

물론 다음처럼 같은 인덱스를 여러 번 지정할 수도 있습니다. 그리고 키워드 인자처럼 표현할 수도 있습니다.

 

>>> "Hi, {0}! You look {1}. The weather's {1}, too.".format('Bob', 'good')
"Hi, Bob! You look good. The weather's good, too."

>>> "You look {look}, {who}!".format(who='Bob', look='good')
'You look good, Bob!'

 

% 기호를 사용해 문자열의 포맷을 지정하는 것처럼 format()에서는 : 기호를 사용합니다.

 

>>> "{:10}".format(365)
'       365'

>>> "{:10}".format('365')
'365       '

 

첫 번째 예에서는 365가 정수라서 오른쪽으로 정렬되어 출력되었습니다. 하지만 두 번째 예에서는 '365'가 문자열이므로 왼쪽으로 정렬되어 출력되었습니다.

 

문자열을 정렬할 때는 다음처럼 합니다.

 

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

>>> "{:>10}".format('365')
'       365'

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

 

순서대로 <는 왼쪽 정렬, >는 오른쪽 정렬, ^는 가운데 정렬을 나타냅니다.

 

이때 공백이 아닌 특정 문자로 채우려면 다음처럼 정렬 기호 바로 앞에 지정합니다.

 

>>> "{:!<10}".format('hello')
'hello!!!!!'

>>> "{:.>10}".format('hello')
'.....hello'

 

%5.2f가 무엇을 의미하는지 기억하시나요? format()에도 다음처럼 :5.2f로 표현할 수 있습니다.

 

>>> import math
>>> radius = 100
>>> area = radius * radius * math.pi

>>> "{:7.2f}".format(area)
'31415.93'

>>> "{:011.2f}".format(area)
'00031415.93'

 

%를 사용해 지정하던 대로 :를 사용하면 됩니다. 전체 자릿수에는 소수점까지 포함한다는 사실에 유의해야 합니다.

 

다음처럼 세 자리마다 쉼표를 넣을 수도 있고, 자릿수 지정, 정렬과 채우기도 가능합니다.

 

>>> import math
>>> radius = 100
>>> area = radius * radius * math.pi

>>> "{:,}".format(round(area))
'31,416'

>>> "{:,.2f}".format(area)
'31,415.93'

>>> "{:20,}".format(round(area))
'              31,416'

>>> "{:20,.2f}".format(area)
'           31,415.93'

>>> "{:<20,}".format(round(area))
'31,416              '

>>> "{:^20,.2f}".format(area)
'     31,415.93      '

 

지금까지 소개한 내용 가운데 대부분은 내장 함수인 format()으로도 같은 결과를 표현할 수 있습니다.

 

>>> import math
>>> radius = 100
>>> area = radius * radius * math.pi

>>> "%s" %format(round(area), ',')
'31,416'

>>> "%s" %format(round(area, 2), ',')
'31,415.93'

>>> "%20s" %format(round(area), ',')
'              31,416'

>>> "%20s" %format(round(area, 2), ',')
'           31,415.93'

>>> "%-20s" %format(round(area), ',')
'31,416              '

 

 

format_map()

format_map()format()과 같은 일을 합니다. 다만, 인자 대신 딕셔너리를 사용합니다.

 

>>> him = {'name':'Robert', 'feel':'good'}
>>> print('Hi, {name}! I feel {feel}.'.format_map(him))
Hi, Robert! I feel good.

 

얼핏 format()의 키워드 인자와 비슷해 보이지만 분명히 다릅니다. namefeel은 딕셔너리의 키입니다. 단, 따옴표는 빼고 지정해야 힙니다.

 

 

translate()

translate()변환 테이블translation table에 따라 문자열을 변환합니다. 변환 테이블은 maketrans()라는 정적 메서드static method 클래스에서 직접 호출하는 메서드를 사용해 만들 수도 있고, 딕셔너리나 리스트 형태로 직접 만들 수도 있습니다. 우선 maketrans()를 사용해 변환 테이블을 만들어 보겠습니다. maketrans()의 인자는 3개까지인데, 인자의 개수에 따라 사용법이 다릅니다.

 

# str_maketrans.py
tr_tbl = {'a':None, 'e':None, 'i':None, 'o':None, 'u':None}

table_1 = str.maketrans(tr_tbl)
table_2 = str.maketrans('aeiou', '*****')
table_3 = str.maketrans('lr', 'LR', 'aeiou')

def main():
    print(f"tr_tbl: {tr_tbl}")
    print(f"table_1: {table_1}")
    print(f"table_2: {table_2}")
    print(f"table_3: {table_3}")

if __name__ == '__main__':
    main()


# result
tr_tbl: {'a': None, 'e': None, 'i': None, 'o': None, 'u': None}
table_1: {97: None, 101: None, 105: None, 111: None, 117: None}
table_2: {97: 42, 101: 42, 105: 42, 111: 42, 117: 42}
table_3: {108: 76, 114: 82, 97: None, 101: None, 105: None, 111: None, 117: None}

 

  • 인자가 하나일 때: 반드시 딕셔너리
    키에는 원래 문자를 유니코드 번호 또는 리터럴로 지정합니다.
    값에는 변환할 새 문자를 유니코드 번호 또는 문자열 리터럴, None으로 지정합니다.
  • 인자가 둘일 때: 반드시 같은 길이의 문자열
    첫 번째는 원래 문자들입니다.
    두 번째는 새 문자들입니다.
    첫 번째 문자가 두 번째 문자로 변환되기 때문에 반드시 두 문자열의 길이가 같아야 합니다.
  • 인자가 셋일 때: 앞 두 문자열은 앞의 경우 그대로, 세 번째는 None으로 변환될 문자들의 열

 

내용이 살짝 복잡하죠? 우선, table_1은 모음을 전부 없애기 위해 만든 변환 테이블입니다. 인자가 하나이므로 딕셔너리로 만들었습니다. table_2는 모음을 전부 '*'로 변환하는 테이블입니다. 그래서 같은 길이의 두 문자열로 만들었습니다. table_3는 소문자 lr를 각각 대문자로 바꾸고, 모음을 모두 없애기 위해 만들었습니다. 어떻게 만들든 결과는 전부 유니코드 번호로 바뀌어 출력되었습니다. 참고로, 유니코드 번호를 알려 주는 내장 함수는 ord()입니다. 반대로 유니코드 번호에 해당하는 문자를 내주는 내장 함수는 chr()입니다.

 

# str_translate.py
import str_maketrans

gr = 'hello, world'

print(f"gr: '{gr}'")
print(f"1. gr.translate(table_1): '{gr.translate(str_maketrans.table_1)}'")
print(f"2. gr.translate(table_2): '{gr.translate(str_maketrans.table_2)}'")
print(f"3. gr.translate(table_3): '{gr.translate(str_maketrans.table_3)}'")


# result
gr: 'hello, world'
1. gr.translate(table_1): 'hll, wrld'
2. gr.translate(table_2): 'h*ll*, w*rld'
3. gr.translate(table_3): 'hLL, wRLd'

 

의도한 대로 모두 출력되었습니다.

 

이번에는 maketrans()를 사용하지 않고 직접 변환 테이블을 만든 후에 translate()로 문자열을 변환하겠습니다.

 

# str_translate_without.py
gr = 'hello, world'
my_table = {ord('a'): None, ord('e'): None, ord('i'): None, ord('o'): None, ord('u'): None}

print(f"gr: '{gr}'")
print(f"my_table: {my_table}")

print(f"gr.translate(my_table): '{gr.translate(my_table)}'")


# result
gr: 'hello, world'
my_table: {97: None, 101: None, 105: None, 111: None, 117: None}
gr.translate(my_table): 'hll, wrld'

 

변환 테이블을 직접 만들 때는 딕셔너리를 사용해야 합니다. 키에는 원래 문자의 유니코드 번호를 지정하고, 값에는 변환할 새 문자를 유니코드 번호나 문자열, 또는 None으로 지정합니다. 여기서는 모음을 전부 없애는 테이블로 만들었습니다.

 

여기까지입니다. 읽어 주셔서 고맙습니다.

 

Today is mutant yesterdays.
영리 목적으로는 저자의 허락 없이 편집, 배포하실 수 없습니다.
Authored by justdoit709@gmail.com

댓글