본문 바로가기
Language & Tool/Python

🌱불변 텍스트 시퀸스, str(문자열)

by 박수무당벌레 2025. 6. 15.

관련글 :

문자열 메서드 참고 https://waydd.tistory.com/35

 

 

1. 문자열(str) 개념

  • Python에서 텍스트 데이터를 표현하는 기본 자료형
  • 변경 불가능(immutable)한 여러개의 문자를 하나로 묶은 시퀀스 자료형
  • 따옴표 (' 또는 ")로 감싸서 정의
  • 순서보장 , 변경가능(불변), 정렬기능 ❌(불변)
s = "Hello! World!"

 

 

2. 주요 특징 정리

 

 - 시퀸스 (인덱싱, 슬라이싱)

  • 문자열은 0부터 인덱싱됨
  • 리스트와 동일하게 [start:stop:step] 구조  ex) 'eovdedn'[n & 1::2]
  • 시퀸스 이므로 min(), max()를 통해 최소/최대 문자도 찾을 수 있음
# 예시
min("hello")  # 'e'
max("hello")  # 'o'

 

- 불변 (immutable)

  • 한 번 생성되면 수정 불가 → 새로운 문자열을 만들어야 함
# 예시
text = "hello"

# 아래처럼 직접 수정할 수 없음
# text[0] = "H"  # TypeError

# 새로운 문자열을 만들어야 함!
new_text = "H" + text[1:]
print(new_text)   # 출력: Hello

 

- len() 사용 가능

  • 파이썬의 자료형은 길이를 내부적으로 저장하고 있음
  • len(s)를 호출하면 새로 계산하지 않고 즉시 반환 → O(1)
# 예시
word = "banana"
length = len(word)
print(f"'{word}'의 길이는 {length}")  # 'banana'의 길이는 6

 

- 형변환

  • str로 형변환(str(x))하면 출력되는 형태와 동일하게 문자열로 값이 바뀜
  • ord(char), chr(code) 을 사용해서 문자 ↔ 아스키 코드 변환도 가능  ex) ord('A') → 65
# 예시
str(True) → "True"
str([1, 2]) → "[1, 2]"

 

- 문자열 연산 가능 (연결, 반복, 포함 여부)

 

1) 문자열 비교 (==, !=, <, >, <=/>=)

  • 사전식 순서(lexicographic order), 즉 유니코드(아스키) 값 순서로 비교됨
  • 왼쪽부터 하나하나 차례로 비교하며, 다르면 즉시 종료 → 최악의 경우 O(N)
  • 대문자는 소문자보다 작게 간주 ('Z' < 'a')
  • 정렬 시에도 이 비교 방식이 그대로 사용됨
print('abc' < 'abd')   # True  ('c' < 'd')
print('apple' < 'banana')  # True  ('a' < 'b')
print('Zoo' < 'apple')     # True  ('Z' < 'a' → Z = 90, a = 97)
※ 추가 설명
- 길이가 다르더라도 먼저 다른 문자가 나오는 위치에서 결정 혹은 길이 비교
- print('apple' < 'apples') # True (앞이 같고, 길이가 짧음)
- print('apple' > 'app') # True (앞이 같고, 길이가 김)

 

2) 문자열 연결 (+ 연산자 사용)

  • 문자열 덧셈은 문자열 객체를 새로 생성함(복사)
  • 아래의 예시처럼 매 반복으로 len(s)가 늘어날 때마다 복사량도 증가
    총 O(1 + 2 + 3 + ... + N) = O(N²) (누적 복사 비용)
  • 루프에서 더 성능 저하, 특히 연결해야할 문자열 길이가 긴 경우 리스트로 누적 후 join으로 연결 처리 추천 O(N) 
# 예시
s = ""
for c in ['a', 'b', 'c', 'd']:
    s += c
    
# 대안 : 리스트 + join
temp = []
for c in ['a', 'b', 'c', 'd']:
    temp.append(c)

s = ''.join(temp)
※ 추가 설명
일반적으로는 join()이 효율적인 경우가 많아 권장
But. 문자열 길이가 매우 짧거나, 리스트 생성 비용이 영향을 줄 정도로 반복 횟수가 많지 않으면 + 연결이 더 빠를 수 있음

 

3) 문자열 반복 (* 연산자 사용)

  • 덧셈과 달리 미리 크기 계산 후 한 번에 생성 (= 빠름)
  • (반복 횟수 * 문자열 길이) 를 미리 계산해서 필요한 메모리를 한 번에 할당
  • 복사도 1회만 일어나며 불필요한 중간 객체가 없음 → O(N) 
# 예시
s = "a" * 10000  # 한 번에 생성

 

4) 포함 여부 (in / not in)

# 예시
'a' in 'cat'       # True
'ca' in 'cat'      # True
'dog' not in 'cat' # True

 

 

3. 주요 메서드 정리

 

- 정리표

  설명 예시
.upper() 대문자로 'abc'.upper() → 'ABC'
.lower() 소문자로 'ABC'.lower() → 'abc'
.capitalize() 첫 문자만 대문자 'hello'.capitalize() → 'Hello'
.swapcase() 대소문자 반전 (A→a, a→A) 'Hello World!'.swapcase()
→ hELLO wORLD!
.title() 각 단어 첫 글자 대문자 'hello world'.title() → 'Hello World'
.strip([chars]) 양쪽 공백/지정 문자 제거 ' abc '.strip() → 'abc'
.lstrip([chars]) 왼쪽 제거 ' abc'.lstrip() → 'abc'
.rstrip([chars]) 오른쪽 제거 'abc '.rstrip() → 'abc'
.replace(old, new[, count]) 문자열 치환 'aabb'.replace('a', 'x') → 'xxbb'
.split([sep[, maxsplit]]) → list[str] 구분자로 분리 → 리스트 'a,b,c'.split(',') → ['a', 'b', 'c']
.join(iterable) 리스트 요소 연결 ','.join(['a', 'b']) → 'a,b'
.count(sub[, start[, end]]) → int 부분 문자열(sub) 등장 횟수, 없으면 0
(빈도)
'banana'.count('a') → 3
.find(sub[, start[, end]]) → int 부분 문자열 첫 위치 반환, 없으면 -1 'banana'.find('na') → 2
.index(sub[, start[, end]]) → int 부분 문자열 첫 위치, 없으면 예외발생 'banana'.index('na') → 2
.startswith(prefix[, start[, end]]) 접두사 여부 검사 'apple'.startswith('a') → True
.endswith(suffix[, start[, end]]) 접미사 여부 검사 'apple'.endswith('e') → True
.isalpha() 알파벳만 포함 여부 'abc'.isalpha() → True
.isdigit() 숫자만 포함 여부 '123'.isdigit() → True
.isalnum() 알파벳+숫자 여부 'abc123'.isalnum() → True
.isspace() 공백만 포함 여부 ' '.isspace() → True
.zfill(width) 왼쪽 0으로 채우기 '42'.zfill(5) → '00042'
.center(width[, fillchar]) 가운데 정렬된 문자열로 반환 'hi'.center(5,'-') → '-hi--'
.partition(sep) → tuple 첫 sep 기준 3등분 'a=b'.partition('=') → ('a', '=', 'b')
.rpartition(sep) → tuple 마지막 sep 기준 3등분 'a=b=c'.rpartition('=') → ('a=b', '=', 'c')
※ str을 리스트로 변환하는 방법 : list() 함수 사용
  s = "hello"
  print(list(s)) # ['h', 'e', 'l', 'l', 'o']
→ list(s)에서 해당 문자열을 한 글자씩 분해하여 새로 리스트로 복사, 변환 (얕은 복사 여부는 의미 없음)

 

 

4. 문자열의 사용 예시

 

- 입력값 처리시 기본 패턴

# 문자열 한 줄 입력 (개행 제거)
s = input().strip()

# 문자열에서 공백 제거 후 출력
print(input().strip().replace(' ', ''))

# 정수 하나 입력
n = int(input().strip())

# 공백으로 구분된 정수 리스트 입력
arr = list(map(int, input().strip().split()))

# a, b 입력받고 a를 b번 반복 출력
a, b = input().strip().split(' ')
print(a * int(b))

# 여러 줄 입력 처리 (예: N줄 받기)
for _ in range(n):
    line = input().strip()

 

- 문자열 포맷

# f-string 사용 (권장)
name = "홍길동"
f"안녕하세요, {name}님!"   # '안녕하세요, 홍길동님!'

# % 포맷 (C 스타일 포맷팅)
name = "Alice"
print("Hello, %s!" % name)    # 'Hello, Alice!'

# .format() 사용 
"{} + {} = {}".format(1, 2, 3)  # '1 + 2 = 3'
※ 포맷 코드
- %s : 문자열
- %d : 정수
- %f : 실수
- %% : % 자체 출력

 

- 이스케이프 문자 리터럴화

print("\n")     # 줄바꿈됨

# Raw 문자열 (권장)
print(r"\n")    # \n 문자 출력됨

# \\ (이스케이프 시퀸스 이스케이핑)
print("\\n")    # \n 문자 출력됨
※ 포맷 코드
- \n : 줄바꿈
- \t : 탭
- \' 또는 \" : 따옴표
- \\ : 백슬래시 자체 출력

 

- 여러줄 문자열과 주석

s = """안녕하세요.
이 문자열은
여러 줄로 구성됩니다."""
print(s)    # '''...'''도 가능