여기서는 문자열을 단순한 글자 덩어리보다 문자들이 순서대로 놓인 시퀀스로 먼저 봅니다.
그래서 문자 하나를 읽고, 일부를 자르고, 정리 메서드를 적용하고, 여러 조각을 합치는 흐름이 같이 따라옵니다.
숏컷 코드
text = "hello world"
first = text[0]
head = text[:5]
upper = text.upper()
joined = ", ".join(["a", "b", "c"])문법
기본형은 인덱싱, 슬라이싱, 정리 메서드, 나누기, join(), f-string까지 같이 보면 됩니다.
text = "hello"
ch = text[0]
part = text[1:4]
clean = text.strip().lower()
parts = text.split(",")
joined = ",".join(parts)
label = f"text={text}"문자열은 시퀀스이지만 list처럼 제자리 수정되는 구조는 아닙니다.
읽고 자르고 조합하는 작업은 많지만, 바꾸면 새 문자열이 만들어진다고 보는 편이 정확합니다.
불변성
문자열은 immutable이라서 수정이 아니라 새 값을 만든다
문자열은 제자리에서 바뀌지 않습니다. 그래서 메서드를 호출하거나 슬라이싱을 해도 보통 새 문자열이 나옵니다.
text = "hello"
updated = text.upper()
print(text) # hello
print(updated) # HELLO이 성질 때문에 문자열은 안전하게 공유하기 쉽지만, 반복문 안에서 계속 +=를 하면 새 문자열을 계속 만드는 비용이 생길 수 있습니다.
읽기와 자르기
문자 하나면 인덱싱, 일부면 슬라이싱으로 본다
문자열도 시퀀스이기 때문에 인덱싱과 슬라이싱을 지원합니다. 값 하나가 목적이면 인덱싱, 부분 문자열이 목적이면 슬라이싱으로 읽으면 됩니다.
word = "Python"
print(word[0]) # P
print(word[-1]) # n
print(word[1:4]) # yth
print(word[:2]) # Py문자열을 "텍스트"로만 보지 말고 "순서 있는 시퀀스"로 같이 볼 수 있어야 이후 list와 tuple도 더 쉽게 연결됩니다.
정리와 조합
공백 정리, 대소문자 변환, 치환은 메서드로 읽는다
문자열은 공백 제거, 대소문자 변환, 검색 같은 기본 작업을 메서드로 자주 처리합니다.
raw = " hello "
clean = raw.strip().title()대표적으로 자주 보는 것은 아래 정도입니다.
strip(): 앞뒤 공백 제거lower(),upper(),title(): 대소문자/표기 정리replace(): 일부 문자열 치환split(): 구분자로 나누기
여러 조각을 합치면 join(), 값 삽입이 있으면 f-string이 맞다
문자열을 만드는 작업은 크게 두 가지로 나뉩니다.
- 조각 여러 개를 구분자로 합친다:
join - 문장 안에 값을 끼워 넣는다:
f-string
names = ["Mina", "Jin", "Sora"]
message = ", ".join(names)
score = 95
label = f"score={score}"짧은 문자열 몇 개를 그냥 붙이는 것은 +로도 되지만, 반복적으로 조합하거나 구분자를 넣는 작업은 join()이 더 분명합니다.
parts = ["a", "b", "c"]
joined = "-".join(parts)
name = "Mina"
label = f"user={name}"즉 이미 문자열 조각이 여러 개 있으면 join(), 문장 안에 값을 끼워 넣는 것이 목적이면 f-string이 더 직접적입니다.
user = {"name": "Mina", "score": 95}
line = f"{user['name']} scored {user['score']}"
csv_line = ",".join(["Mina", "95"])즉 f-string은 문장 안 값 삽입, join()은 이미 분리된 조각 결합이라는 차이로 보면 헷갈림이 줄어듭니다.
도구 경계
단순 자르기와 치환은 메서드, 구조 파싱은 다른 도구로 넘어간다
단순 자르기와 치환은 문자열 메서드로 충분하지만, 조건이 복잡해지면 split(), partition(), 정규식 같은 도구가 더 잘 맞습니다.
문자열 메서드로 모든 파싱을 밀어붙이는 건 보통 오래 못 갑니다.
line = "name=mina"
parts = line.split("=") # ["name", "mina"]
left, sep, right = line.partition("=")구분자가 한 번만 나온다는 전제가 분명하면 partition()이 더 직접적입니다. 여러 조각으로 쪼개야 하면 split()이 자연스럽습니다.
주의할 점
문자열은 제자리 수정이 되지 않습니다. 인덱스로 값을 바꾸려 하면 오류가 납니다.
# ❌ 문자열은 immutable
text = "cat"
text[0] = "b"
# ✅ 새 문자열을 만든다
text = "b" + text[1:]# ❌ 이미 문자열 리스트가 있는데 +로 반복 결합
result = ""
for part in ["a", "b", "c"]:
result += part
# ✅ 조각을 한 번에 합침
result = "".join(["a", "b", "c"])# ❌ split()은 구분자를 제거하고 리스트를 만든다
text = "a,b,c"
parts = text.split(",")
# ✅ 구분자를 유지한 좌우 분리는 partition()이 더 직접적일 수 있다
left, sep, right = text.partition(",")# ❌ 문자열을 수정 가능한 문자 배열처럼 읽으면 안 된다
text = "abc"
chars = list(text) # ["a", "b", "c"]
# ✅ 진짜 수정 가능한 시퀀스가 필요하면 list로 바꿔서 다룬다
chars[0] = "z"
text = "".join(chars)참고 링크
2 sources