Code › codeit-ai-sprint
파이썬의 딕셔너리와 문자열
코드잇 AI 엔지니어 스프린트 pre-course의 마지막 파이썬 강의
오늘은 pre-course 파이썬 강의 세 개 중 마지막 강의를 끝냈다. 사전, 영어 단어장, 리스트와 문자열, aliasing 같은 내용을 봤고, 실습으로 사전 뒤집기나 투표 집계하기도 풀어봤다. 전체적으로는 기초 문법을 다시 정리하는 흐름이었지만, 이번에는 딕셔너리와 문자열에서 파이썬이 데이터를 다루는 방식이 조금 더 눈에 들어왔다.
먼저 문자열이 인덱싱은 되지만 수정은 안 된다는 점이 다시 걸렸다. 예를 들어 word[0]처럼 접근하면 첫 글자를 꺼낼 수 있지만, word[0] = "H"처럼 바꾸려고 하면 에러가 난다. 처음에는 단순히 리터럴이라서 그런가 싶었는데, 정확히는 파이썬의 문자열 객체 자체가 immutable, 즉 한 번 만들어지면 내부 값을 바꿀 수 없는 타입이 되기 때문. 수정하려면 메모리를 새로 할당해야해서 성능상 불리하긴 하다.
word = "hello"
print(word[0]) # h
# word[0] = "H" # TypeError
word = "H" + word[1:]
print(word) # Hello
C++의 std::string은 인덱스로 특정 문자를 바꿀 수 있다. 반면 TypeScript나 JavaScript의 문자열은 파이썬처럼 불변이라서 text[0] = "H" 같은 방식으로 실제 문자열을 바꾸지는 못한다. 겉으로는 인덱싱 문법이 비슷해 보여도, 그 값이 수정 가능한 컨테이너인지 아니면 새 문자열을 만들어야 하는 타입인지는 언어마다 다르다.
강의에서 딕셔너리의 keys(), values(), items() 함수들을 배웠는데, 이들의 리턴 타입이 궁금했다. 새 리스트를 매번 만들어서 주지는 않을 것 같았는데, 찾아보니 dict view 객체였다. dict_keys, dict_values, dict_items처럼 딕셔너리를 바라보는 view를 돌려주고, 이 객체는 원본 딕셔너리의 변화를 반영한다.
scores = {"kim": 90, "lee": 85}
keys = scores.keys()
items = scores.items()
print(keys) # dict_keys(['kim', 'lee'])
print(list(items)) # [('kim', 90), ('lee', 85)]
scores["park"] = 100
print(keys) # dict_keys(['kim', 'lee', 'park'])
이 방식이 좋은 이유는 메모리와 의미가 둘 다 깔끔하기 때문이다. 딕셔너리에 키가 아주 많을 때 keys()를 부를 때마다 리스트를 새로 만들면 불필요한 복사가 생긴다. view 객체는 원본 데이터를 복사하지 않고 바라보기 때문에 훨씬 가볍고, 원본이 바뀌면 그 변화도 자연스럽게 보인다. C++로 치면 소유하지 않고 바라보는 view나 iterator에 가깝고, TypeScript의 Object.keys()가 배열을 새로 만들어주는 것과는 다르다.
물론 리스트와 완전히 같지는 않다. view 객체는 반복문에 바로 쓸 수 있지만, 인덱싱은 안 된다. 그래서 첫 번째 키를 바로 keys[0]처럼 꺼낼 수는 없다. 순서대로 접근하거나 리스트처럼 다루고 싶다면 명시적으로 변환해야 한다.
scores = {"kim": 90, "lee": 85}
for name in scores.keys():
print(name)
names = list(scores.keys())
print(names[0])
파이썬의 음수 인덱싱도 다시 보면 꽤 재미있다. 리스트나 문자열에서 -1은 마지막 요소를 뜻한다. 다른 언어에서는 보통 길이를 구해서 length - 1로 접근하는 일이 많은데, 파이썬은 끝에서부터 세는 문법을 언어 차원에서 제공한다. 그래서 마지막 값이나 뒤쪽 일부를 꺼낼 때 코드가 짧아진다.
letters = ["a", "b", "c"]
print(letters[-1]) # c
print(letters[-2]) # b
이번 강의까지 끝내면서 코드잇 AI 엔지니어 스프린트 pre-course의 파이썬 강의 세 개를 모두 마쳤다. 이미 알고 있던 내용도 있었지만, 이런 차이를 하나씩 다시 확인해보는 시간이 좋았다. 특히 파이썬은 AI나 데이터 쪽에서 계속 쓰게 될 언어라서, 문법을 대충 기억하는 수준이 아니라 왜 이렇게 동작하는지까지 정리해두는 편이 좋을 것 같다.
이제 머신러닝 관련 강의도 조금 들어볼 생각이다. 본 과정에 들어가기 전까지 시간이 많지는 않지만, 적어도 파이썬의 기본 감각은 다시 잡았으니 다음에는 그 위에 올라가는 개념을 천천히 이어서 보면 될 것 같다.