f-string으로 문자열 포맷팅(Formatting)

안녕하세요 :D

오늘은 파이썬을 공부하다가 처음 알게 된 f-string에 대해 좀 더 공부해 보고 정리해보려고 합니다⭐

(Effective Python 2nd Edition Item4에 나오는 내용을 참고하였습니다😊)

 

형식화(Formatting)는 미리 정의된 문자열에 데이터 값을 끼워 넣어 사람이 보기 좋은 문자열로 저장하는 과정입니다.

파이썬에는 4가지 방식으로 문자열을 포맷팅할 수 있는데요. 이 중 1가지 방식을 제외한 나머지 모두 단점이 존재합니다😥

 

#1 % 형식화 연산자(% formatting operator)

가장 흔한 포맷팅 방식인 % 포맷팅 연산자입니다!

% 연산자 왼쪽에는 미리 정의된 텍스트 템플릿인 형식 문자열이 들어가고, 오른쪽에는 템플릿에 끼워 넣을 값이 단일 값 혹은 tuple로 들어갑니다.

a = 0b10111011
b = 0xc5f
print('Binary is %d, hex is %d' % (a, b))  # Binary is 187, hex is 3167

 

C에서 'prinf 스타일'로 사용한 적이 있으면 익숙한 방식인데요. C언어의 printf에 사용할 수 있는 대부분의 형식 지정자를 지원하고, 소수점 위치나 패딩(padding), 채워 넣기, 좌우 정렬 등도 제공합니다.

 

하지만 여기에는 4가지 문제점이 있습니다💦

1️⃣ 형식화 식의 오른쪽에 있는 tuple 내 데이터 값의 순서를 바꾸거나 값의 타입을 바꾸면 타입 변환이 불가능하므로 오류가 발생할 수 있습니다.

test = 'age: %i' % '111' 
# Traceback (most recent call last): File "", line 1, in <module> TypeError: %i format: a number is required, not str

2️⃣ 형식화를 하기 전에 값의 변경이 일어나면, tuple의 길이가 너무 길어져 가독성이 나빠집니다.

3️⃣ 같은 값을 여러 번 사용할 경우, tuple에 같은 값을 여러 번 반복해야합니다.

4️⃣ 첫 번째와 세 번째 문제점은 tuple 대신 dictionary를 사용하면 해결되지만, 식이 더 길어지고 가독성의 문제가 더 많아집니다.

 

#2 내장 함수 format과 str.format

💁‍♀️이후 Python3부터 새로운 포맷팅을 제시합니다.

물론... Python3에서도 % operator를 지원하지만 공식문서에서는 권장하지 않는다고 나와있어요 ㅎㅎ..

a = 1234.5678
formatted = format(a, ',.2f')
print(formatted)  # 1,234.57

b = 'my string'
formatted = format(b, '^20s')
print('*', formatted, '*')  # * my string *

`{}`을 사용해서 포맷팅 할 때는 위 예제와 같이, 포맷팅 하는 값의 데이터 타입에 관계없이 그냥 `{}`을 써주기만 하면 됩니다. 문자열이든, 정수든, 실수든 다 `{}`을 써서 받아올 수 있습니다. 아주 큰 장점이죠.

 

위치 지정자에 콜론과 형식 지정자를 붙여 넣어 형식을 지정할 수도 있습니다🙆‍♀️

print(1234567890) #자릿 수 표현 위함
print('{:>3}'.format('5')) # >는 오른쪽정렬
print('{:<3}'.format('5')) # <는 왼쪽정렬
print('{:^3}'.format('5')) # ^는 가운데정렬
print('{:0>3}'.format(5)) # 빈자리를 0으로 채울수도 있음

 

#3 f-string

f-string 포맷팅은 Python 버전 3.6부터 사용할 수 있는 따끈따끈한 기능입니다😁

str.format이 % operator에 비해 강력하고 사용하기 쉽지만, f-string은 더욱더 간편해졌습니다.

 

일반적인 문자열 앞에 f 또는 F 문자만 붙여주면 f-string이 됩니다❗

중괄호(brace)를 사용하면 f-string 안에 파이썬의 표현식(expression)을 삽입할 수 있는데요.

👉 f'문자열 {변수} 문자열'
key = 'my_var'
value = 1.234

formatted = f'{key} = {value}'
print(formatted)  # my_var = 1.234

이처럼 문자열 안에 어떤 변수나 표현식(expression)을 삽입할 때 f-string의 진가가 발휘되기 시작합니다🌟

 

사실상 f-string을 사용하면 파이썬에서 상상할 수 있는 모든 표현식을 문자열 안에 삽입할 수 있기 때문에 활용도가 무궁무진하다고 볼 수 있습니다. f-string을 사용하면 문자열 안에서 심지어 함수를 호출할 수 있습니다.

 

그리고 % operator 나 str.format 함수를 사용하는 경우보다 코드의 길이가 항상 짧아집니다.

위치 지정자 중괄호 안에 완전한 파이썬 식을 넣을 수 있어 값의 변경이 간결하게 끝나기도 합니다.

for i, (item, count) in enumerate(pantry):
    old_style = '#%d: %-10s = %d' % (
    i + 1,
    item.title(),
    round(count))

    new_style = '#{}: {:<10s} = {}'.format(
    i + 1,
    item.title(),
    round(count))

    f_string = f'#{i+1}: {item.title():<10s} = {round(count)}'

    assert old_style == new_style == f_string

형식 지정자 옵션에 파이썬 식도 넣을 수 있죠.😎

places = 3
number = 1.23456
print(f'My number is {number:.{places}f}')  # My number is 1.235

Effective Python(2nd edition)에서는 f-string 사용을 권장하더라구요.. 저는 아직 str.format이 조금 더 편하답니다ㅠㅠ

지금부터는 f-string에 적응해볼려고 합니다!

사실 ML할 때는 문자열 포맷팅할 일이 크게 없는거 같아요ㅎㅎ

그래도 사용하긴 하니까 한 번 정리를 해보았습니다💨