replace는 문자열 안에서 특정 문자열을 다른 문자열로 바꿔줍니다. 중요한 점은 문자열은 불변(immutable)이므로, 원본이 변경되는 것이 아니라 새로운 문자열이 반환된다는 것입니다.
# replace로 문자열 바꾸기
s = "Hello World"
new_s = s.replace("World", "Python")
print(new_s) # Hello Python
print(s) # Hello World (원본은 그대로)
바뀐 결과를 유지하고 싶다면 변수에 다시 할당하면 됩니다.
여러 문자를 한꺼번에 바꾸고 싶을 때는 translate와 maketrans를 조합하여 사용합니다.
# maketrans로 변환 테이블을 만들고 translate로 적용
table = str.maketrans("aeiou", "12345")
result = "apple".translate(table)
print(result) # 1ppl2
💡
replace는 문자열 단위,translate는 문자(글자) 단위로 치환한다는 차이가 있습니다.
split은 기본적으로 공백을 기준으로 문자열을 분리하여 리스트로 만듭니다. 기준 문자열을 직접 지정할 수도 있습니다.
# 공백 기준 분리
words = "Hello World Python".split()
print(words) # ['Hello', 'World', 'Python']
# 특정 문자열 기준 분리
data = "2024-01-15"
parts = data.split("-")
print(parts) # ['2024', '01', '15']
join은 split의 반대입니다. 구분자 문자열과 문자열 리스트의 요소를 연결하여 하나의 문자열로 만듭니다.
# join으로 리스트를 문자열로 연결
words = ['Hello', 'World', 'Python']
result = " ".join(words)
print(result) # Hello World Python
# 다른 구분자 사용
result2 = "-".join(['2024', '01', '15'])
print(result2) # 2024-01-15
split과 join의 관계를 정리하면 다음과 같습니다.
| 메서드 | 방향 | 예시 |
|---|---|---|
split(구분자) | 문자열 → 리스트 | "a-b-c".split("-") → ['a','b','c'] |
구분자.join(리스트) | 리스트 → 문자열 | "-".join(['a','b','c']) → "a-b-c" |
s = "Hello World"
# upper: 모두 대문자로
print(s.upper()) # HELLO WORLD
# lower: 모두 소문자로
print(s.lower()) # hello world
공백을 삭제하는 메서드는 세 가지가 있으며, 삭제 방향이 다릅니다.
| 메서드 | 삭제 위치 |
|---|---|
lstrip() | 왼쪽(left) 공백 삭제 |
rstrip() | 오른쪽(right) 공백 삭제 |
strip() | 양쪽 공백 삭제 |
s = " Hello World "
print(s.lstrip()) # "Hello World "
print(s.rstrip()) # " Hello World"
print(s.strip()) # "Hello World"
ljust는 문자열을 지정된 길이로 만든 뒤 왼쪽으로 정렬하고, 남는 공간을 공백으로 채웁니다. rjust는 그 반대로 오른쪽 정렬입니다.
s = "Hello"
# ljust: 왼쪽 정렬, 남는 공간은 오른쪽에 공백
print(s.ljust(10)) # "Hello "
# rjust: 오른쪽 정렬, 남는 공간은 왼쪽에 공백
print(s.rjust(10)) # " Hello"
center는 문자열을 가운데로 정렬합니다. 가운데 정렬했을 때 남는 공간이 홀수라면 왼쪽에 공백이 한 칸 더 들어갑니다.
s = "Hello"
print(s.center(11)) # " Hello "
print(s.center(10)) # " Hello " ← 왼쪽 2칸, 오른쪽 3칸 (왼쪽이 1칸 더)
zfill은 문자열의 왼쪽에 0을 채워 지정된 길이로 만듭니다. 숫자 문자열을 다룰 때 유용합니다.
# zfill: 왼쪽에 0 채우기
print("42".zfill(5)) # 00042
print("123".zfill(5)) # 00123
print("hello".zfill(8)) # 000hello
문자열 메서드는 새로운 문자열을 반환하므로, 메서드를 연결해서 호출하는 메서드 체이닝이 가능합니다.
# 메서드 체이닝: 공백 제거 → 소문자 변환 → 특정 문자열 치환
result = " Hello World ".strip().lower().replace("world", "python")
print(result) # hello python
find는 문자열에서 특정 문자열을 찾아 인덱스를 반환하고, 없으면 -1을 반환합니다. 같은 문자열이 여러 개일 경우 처음 찾은 인덱스를 반환합니다.
rfind는 오른쪽에서부터 찾습니다.
s = "apple pineapple"
print(s.find("pl")) # 2 (왼쪽에서부터 처음 찾은 위치)
print(s.rfind("pl")) # 12 (오른쪽에서부터 처음 찾은 위치)
print(s.find("xyz")) # -1 (없으면 -1)
index와 rindex도 문자열의 위치를 찾지만, 문자열이 없을 때 에러가 발생한다는 차이가 있습니다.
| 메서드 | 문자열이 없을 때 |
|---|---|
find / rfind | -1 반환 |
index / rindex | ValueError 발생 |
s = "hello"
# find: 없으면 -1
print(s.find("xyz")) # -1
# index: 없으면 에러
# print(s.index("xyz")) # ValueError: substring not found
💡 문자열이 있는지 확실하지 않다면
find를 사용하는 것이 안전합니다.index는 문자열이 반드시 존재한다고 확신할 때 사용하세요.
s = "banana"
print(s.count("an")) # 2
print(s.count("a")) # 3
파이썬에서 문자열 안에 값을 넣는 방법은 세 가지가 있습니다. 뒤로 갈수록 더 현대적이고 간결한 방식입니다.
%)%로 시작하고 자료형을 뜻하는 문자가 붙는 방식입니다.
| 서식 지정자 | 의미 |
|---|---|
%s | 문자열 (string) |
%d | 정수 (decimal) |
%f | 실수 (float) |
# 서식 지정자로 값 하나 넣기
print("이름: %s" % "홍길동") # 이름: 홍길동
# 값 여러 개 넣기 (튜플 사용)
print("이름: %s, 나이: %d" % ("홍길동", 25)) # 이름: 홍길동, 나이: 25
{} 중괄호 안에 인덱스를 지정하고, format 메서드로 값을 넣습니다.
# 인덱스로 지정
print("이름: {0}, 나이: {1}".format("홍길동", 25)) # 이름: 홍길동, 나이: 25
# 같은 인덱스를 여러 번 사용
print("{0}님, 반갑습니다 {0}님!".format("홍길동")) # 홍길동님, 반갑습니다 홍길동님!
# 이름으로 지정 (인덱스 대신)
print("이름: {name}, 나이: {age}".format(name="홍길동", age=25))
문자열 앞에 f(formatting)를 붙이고, {} 안에 변수를 직접 넣는 방식입니다. 가장 간결하고 가독성이 좋아 파이썬 3.6 이후로 가장 많이 사용됩니다.
# f-string: 변수를 직접 사용
name = "홍길동"
age = 25
print(f"이름: {name}, 나이: {age}") # 이름: 홍길동, 나이: 25
# 중괄호 안에서 연산도 가능
print(f"내년 나이: {age + 1}") # 내년 나이: 26
세 가지 방식을 비교하면 다음과 같습니다.
| 방식 | 문법 | 권장도 |
|---|---|---|
| 서식 지정자 | "이름: %s" % name | ⭐ (레거시) |
| format | "이름: {0}".format(name) | ⭐⭐ |
| f-string | f"이름: {name}" | ⭐⭐⭐ (권장) |