HOME > python > basic

Python - String Formatting 방법 정리(%, Str formatting, f-stirng)

By JS | 08 Feb 2020

Python의 String formatting에 대해서 정리하였습니다.

문자열을 formatting하는 방법은 다음과 같은 방법이 있습니다.

  • % formatting: 오래된 스타일의 formatting 방법
  • String formatting: 새로은 스타일의 formatting 방법
  • f-string: Python 3.6 이상에서 사용할 수 있는 새로운 스타일의 formatting 방법

동일한 문자열에 대해서 위의 3개의 방식으로 각각 어떻게 적용하는지 알아보겠습니다.

기본 형식

기본 형식 입니다. % formatting, String formatting, f-string 순서로 적용하였습니다.

temperature = 202
measure = 'Fahrenheit'
print('Water boils at %d degrees %s' % (temperature, measure))     # 1
print('Water boils at {} degrees {}'.format(temperature, measure)) # 2
print(f'Water boils at {temperature} degrees {measure}')           # 3
  1. C style처럼 사용할 수 있습니다.
  2. {}에 대응하는 것을 format()의 인자로 전달할 수 있습니다.
  3. 요즘 만들어진 언어에서 지원하는 formatting 스타일과 유사합니다. 문자열 앞에 f를 입력하면 f-string이 적용됩니다. {}에 변수를 직접 입력하기 때문에 가독성이 좋습니다.

결과

Water boils at 202 degrees Fahrenheit
Water boils at 202 degrees Fahrenheit
Water boils at 202 degrees Fahrenheit

Padding, Aligning

Padding은 왼쪽에, 문자열은 오른쪽에 정렬하는 방법입니다.

string = 'test'
print('%10s' % (string))
print('{:>10}'.format(string))
print(f'{string:>10}')

결과를 보시면, 문자열은 오른쪽으로 정렬되었습니다. 그리고 10개의 공간에서 문자열 4개를 제외한 6개의 공백은 왼쪽에 배치되었습니다.

      test
      test
      test

위와 반대로 Padding은 오른쪽에, 문자열은 왼쪽에 정렬하는 방법입니다. (String formattingf-string에서 :뒤에 <를 입력해도 되고 생략해도 됩니다.)

string = 'test'
print('%-10s' % (string))
print('{:10}'.format(string))
print(f'{string:10}')

결과

test      
test      
test      

Padding을 공백으로 채우지 않고 특정 문자로 채우는 방법입니다. * 대신에 원하는 문자로 변경할 수 있습니다.

string = 'test'
print('{:*>10}'.format('test'))
print(f'{string:*>10}')

print('{:*<10}'.format('test'))
print(f'{string:*<10}')

결과

******test
******test
test******
test******

가운데 정렬을 하는 방법입니다. ^를 사용합니다.

string = 'test'
print('{:^10}'.format('test'))
print(f'{string:^10}')

print('{:*^10}'.format('test'))
print(f'{string:*^10}')

결과

   test   
   test   
***test***
***test***

문자열 자르기

문자열의 길이를 5개로 제한하는 예제입니다.

string = 'xylophone'
print('%-.5s' % (string))
print('{:.5}'.format(string))
print(f'{string:.5}')

결과

xylop
xylop
xylop

숫자 출력

float으로 출력하는 예제입니다. float은 소수 6자리까지만 표현합니다.

number = 3.141592653589793
print('%f' % (number))
print('{:f}'.format(number))
print(f'{number:f}'.format(number))

print(f'{number}')

결과

3.141593
3.141593
3.141593
3.141592653589793

다음은 소수점 아래로 2자리까지만 출력하는 예제입니다.

number = 3.141592653589793
print('%.2f' % (number))
print('{:.2f}'.format(number))
print(f'{number:.2f}')

결과

3.14
3.14
3.14

다음은 Padding과 소수점 아래로 2자리만 출력하도록 적용한 예제입니다. 08의 의미는 8개의 문자로 출력하며 남은 공간은 0으로 모두 채우겠다는 것입니다.

number = 3.141592653589793
print('%08.2f' % (number))
print('{:08.2f}'.format(number))
print(f'{number:08.2f}')

결과

00003.14
00003.14
00003.14

다음은 Integer에 padding을 적용한 예제입니다.

number = 12
print('%04d' % (number))
print('{:04d}'.format(number))
print(f'{number:04d}')

결과

0012
0012
0012

다음은 위의 예제와 유사하지만, 양수에 +를 함께 출력합니다.

number = 12
print('%+04d' % (number))
print('{:+04d}'.format(number))
print(f'{number:+04d}')

결과

+012
+012
+012

str, repr 출력

객체의 __str____repr__을 다양한 방식으로 문자열에 출력하는 예제입니다.

class Comedian:
    def __init__(self, first_name, last_name, age):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age

    def __str__(self):
        return f"{self.first_name} {self.last_name} is {self.age}."

    def __repr__(self):
        return f"{self.first_name} {self.last_name} is {self.age}. Surprise!"

new_comedian = Comedian("Eric", "Idle", "74")
print("%s" % (new_comedian))
print("%r" % (new_comedian))

print("{0!s}".format(new_comedian))
print("{0!r}".format(new_comedian))

print(f'{new_comedian}')
print(f'{new_comedian!r}')

결과

Eric Idle is 74.
Eric Idle is 74. Surprise!
Eric Idle is 74.
Eric Idle is 74. Surprise!
Eric Idle is 74.
Eric Idle is 74. Surprise!

Named placeholders

keyword를 이용하여 객체를 formatting에 적용하는 예제입니다.

data = {'first': 'Hodor', 'last': 'Hodor!'}
print('%(first)s %(last)s' % data)
print('{first} {last}'.format(**data))

결과

Hodor Hodor!
Hodor Hodor!

String formatting의 경우 Python 3.2 이상에서는 다음처럼 적용할 수도 있습니다. 결과는 위와 동일합니다.

print('{first} {last}'.format_map(data))

Get item, Get attribute

아이템을 객체로 부터 가져와서 formatting에 적용하는 예제입니다. f-string의 경우 내부에서 map의 key를 입력할 때 '(작은따옴표)을 사용하기 때문에 문자열은 "(큰따옴표)로 표현해야 합니다. (반대로 적용해도 됩니다.)

person = {'first': 'Jean-Luc', 'last': 'Picard'}
print('{p[first]} {p[last]}'.format(p=person))
print(f"{person['first']} {person['last']}")

결과

Jean-Luc Picard
Jean-Luc Picard

다음은 배열에 대한 예제입니다.

data = [4, 8, 15, 16, 23, 42]
print('{d[4]} {d[5]}'.format(d=data))
print(f'{data[4]} {data[5]}')

결과

23 42
23 42

다음은 클래스에 대한 예제입니다.

class Plant(object):
    type = 'tree'
    kinds = [{'name': 'oak'}, {'name': 'maple'}]

print('{p.type}: {p.kinds[0][name]}'.format(p=Plant()))

p = Plant()
print(f"{p.type}: {p.kinds[0]['name']}")

결과

tree: oak
tree: oak

Datetime

다음은 datetime에 대한 예제입니다.

from datetime import datetime
print('{:%Y-%m-%d %H:%M}'.format(datetime(2001, 2, 3, 4, 5)))

date = datetime(2001, 2, 3, 4, 5)
print(f"{date:%Y-%m-%d %H:%M}")

결과

2001-02-03 04:05
2001-02-03 04:05

Parameterized format

인자로 값을 전달하여 formatting을 적용할 수 있습니다.

다음 예제는 위에서 소개한 정렬과 padding을 적용하는 예제입니다.

p_align = '^'
p_width = '10'
string = 'test'
print('{:{align}{width}}'.format(string, align=p_align, width=p_width))
print(f'{string:{p_align}{p_width}}')

결과

   test   
   test   

다음은 datetime에 적용한 예제입니다.

from datetime import datetime
dt = datetime(2001, 2, 3, 4, 5)
print('{:{dfmt} {tfmt}}'.format(dt, dfmt='%Y-%m-%d', tfmt='%H:%M'))
print(f'{dt:{"%Y-%m-%d"} {"%H:%M"}}')

결과

2001-02-03 04:05
2001-02-03 04:05

참고