프로그래밍백엔드 개발자

파이썬은 문자열(`str`)을 어떻게 처리하나요? 파이썬의 문자열 불변성은 예를 들어 리스트와 어떻게 다르나요? 큰 데이터 세트를 조작할 때 문자열 작업의 어떤 미묘한 부분이 있을까요?

Hintsage AI 어시스턴트로 면접 통과

답변

파이썬에서 문자열(str)은 불변 객체로, 생성된 후에는 내용이 변경될 수 없습니다. 문자열을 수정하는 모든 작업(예: 연결이나 문자 대체)은 새 문자열 객체를 생성합니다. 이는 코드의 다른 부분에서 누군가가 문자열을 암묵적으로 변경할까 걱정할 필요가 없어서 안전하고 예측 가능한 작업을 보장합니다.

s = 'Hello' s2 = s.replace('H', 'J') # s는 'Hello'로 남고, s2는 'Jello'가 됩니다.

문자열과 달리, 파이썬의 리스트는 가변 객체입니다. 그 내용은 인덱싱이나 메소드를 통해 제자리에서 변경할 수 있어, 같은 리스트를 여러 곳에서 사용할 때 암묵적인 효과를 초래할 수 있습니다.

성능 관점에서 볼 때: 큰 문자열을 자주 수정해야 하는 경우(예: 루프 안에서), 불변성 메커니즘이 메모리 할당 과다와 느린 코드 실행으로 이어질 수 있습니다. 이러한 경우 문자열 조각을 모으기 위해 리스트를 사용하고, 이를 ''.join()을 통해 결합하는 것이 좋습니다.

예시:

# 나쁨(큰 데이터 세트에 대해 느림): s = '' for word in words: s += word # 매 단계마다 새로운 문자열이 생성됩니다. # 좋음: parts = [] for word in words: parts.append(word) s = ''.join(parts)

함정 질문

질문: 왜 "s += 'abc'"가 문자열에 대해 "s = s + 'abc'"보다 더 빠른가요?

답변: 이러한 질문은 사람이 두 작업이 실제로 문자열에 대해 동등하다는 것을 이해하고 있는지 확인하기 위해 합니다 (s += 'abc's = s + 'abc'와 같이 새 객체를 생성합니다) — 파이썬에서의 타입 동작 방식이 그렇게 되어 있습니다. 리스트의 경우 행동이 다릅니다. list += [...]는 객체를 변형하지만, list = list + [...]는 새 객체를 생성합니다. 문자열의 경우 항상 새로운 문자열입니다.

s = 'hi' s += 'abc' # 새 객체, 원래 문자열은 변하지 않습니다. def compare(s): a = s a += 'abc' # id(a) != id(s) <-- 메모리의 서로 다른 객체

주제의 미묘함을 모르고 발생하는 실제 오류 사례


이야기

메가바이트 길이의 큰 로그를 처리해야 하는 프로젝트에서 개발자는 루프에서 문자열을 단순히 연결하는 방식을 사용했습니다. 결과적으로 성능이 크게 저하되고 메모리 사용이 급증했습니다. 리스트와 join()으로 최적화한 후 실행 시간이 20배 줄어들었습니다.


이야기

한 프로젝트에서 인덱스를 통해 문자열의 문자를 "수정"하려고 할 때, 프로그래머는 원래 문자열이 변경될 것으로 기대했습니다. TypeError: 'str' object does not support item assignment 오류가 발생했습니다. 몇 시간을 소모한 후, 디버거는 슬라이스를 사용하여 새로운 문자열을 만들어야 했습니다.


이야기

문자열 목록의 각 요소에 접미사를 추가하기 위해 함수를 호출할 때, 개발자 중 한 명은 문자열이 "제자리에서" 변경될 것이라고 예상했습니다. 결과적으로 함수는 None을 반환했고, 모든 문자열은 원래 상태로 유지되었습니다.