dictionary
언제 써야해?
- 동적 데이터를 관리하고 싶을 떄
- 빠르고, flxible 하다.
- 이유
- hash table 이나 associate array 라고 불리는 데이터 구조 안에 값을 저장
- (분할상환 복잡도 로) 상수 시간에 원소를 삽입하거나 찾을 수 있다.
언제 쓰지 말아야 해?
- 읽고 쓰기 어려운 data 타입이다. 특히 nested structures를 다룰 때 가독성이 떨어진다.
- 데이터에 built-in validation or constraints를 설정할 수 없다.
- (dictionary, long tuple, 다른 내장 타입이 복잡하게 내포된 데이터를 값으로 사용하는)
dictionary
를 만들지 말라.
- 내부 상태를 표현하는
dictionary
가 복잡해지면, 이 데이터를 관리하는 코드를 여러 클래스로 나눠서 재작성하라.
dictionary
안에 dictionary를 포함시키지 말라. 코드가 읽기 어려워지고, 여러분 스스로도 유지 보수의 ‘악몽’ 속으로 들어가는 셈이다.
- 어떠 내장 타입이던 내포 단계가 2 단계 이상 되면, 더 이상 dictionary, list, tuple 계층을 추가하지 말라. ( 2단계 까지 허용)
list
언제 써야해?
- mutable (동적인/가변적인) 데이터 관리
언제 쓰지 말아야 해?
- 파이썬 리스트는 무겁다. (이유: 동적배열 + 가변성)
tuple
언제 써야해?
- immutable (정적인/불변인) 데이터 관리
언제 쓰지 말아야 해?
- immutable 데이터 관리할 때, 원소가 4개 이상인 tuple은 쓰지 말고, 대신
collection 내장 모듈의 namedtuple
사용을 고려하라.
장점
- 구현 특성 상, 리스트와 비교해서 더 메모리용량을 아끼고 퍼포먼스를 향상시킴
단점
tuple
에 있는 요소를 접근할 때 순서를 기억해서 순서로 접근해야 함
namedtuple
언제 써야해?
- 완전한 class 가 제공하는 유연성이 필요하지 않고, 작은 불변 데이터 container가 필요할 때
- tuple 의 특성인 불변성과, dictionary의 장점인 label 있음을 둘 다 쓰고 취하고 싶을 때
- tuple의 원소가 4개 이상이 되어서, 각 원소가 어떤 것을 내포하고 있는지 기억하기 힘들어질 때
- 위의
dictionary 언제 쓰지 말아야 해
의 경우에 해당할 때 고려
언제 쓰지 말아야 해?
namedtuple
의 property가 4-5개보다 더 많아지면, dataclasses
내장 모듈을 사용하라.
장점
- 읽기 쉽다.
- positional argument를 사용할 수 있고, keyword argument를 사용할 수 있다.
- 필드에 접근할 때는 attribute 이름으로도 가능하고, 숫자 index를 사용해 접근할 수도 있다.
- unpacking 가능 /
__repr__
사용 가능
- attribute 값에 대한 iteration도 가능하다.
단점
- default argument 값 설정이 부자연스럽다.
- 데이터에 built-in validation or constraints를 설정할 수 없다.
dataclass
언제 써야해?
- 가변 데이터 형 중 , dictionary와 class의 중간 규모
- data를 담기 위함이지만, 많은 추가 행동이 필요하지 않은 경우
- 아래 class의 단점을 극복한 data 형을 정의하고 싶을 떄
- 위의
dictionary 언제 쓰지 말아야 해
의 경우에 해당할 때 고려
- chatGPT의 대답
- 데이터에 built-in validation or constraints를 설정할 수 있다.
- 읽기 쉽고, 다소 복잡한 데이터 구조를 표현하는데 도움이 된다.
- data구조를 정의하는데 도움이 된다.
- 데이터를 접근하고 변경하는데에 편리하다.
- 다른 파트의 코드나 시스템 간 data 전송이 필요할 떄, data 포멧에 대한 표준화를 제공한다.
- 코드를 test하거나 test data를 생성할 떄, 'dataclass'는 data를 명확하고 간결한 방법으로 정의하는데 도움을 준다.
- data를 file으로 serialize하거나 network를 통해 넘기고 싶을 떄, 'dataclass'는 data 구조를 정의하는데 도움을 주고, serializing / deserializng 메서드를 제공해줄 수 있다.
언제 쓰지 말아야 해?
- 규모가 크고 추가 행동이 많아지면, class 사용을 고려하라.
- 추가 데이터 field가 계속 들어갈 공산이 있으면, 적합하지 않다.
class
언제 써야해?
- 동적(가변성)을 지원해야 하거나, 간단한 데이터 컨테이너 이상의 동작이 필요한 경우부터 사용 고려
namedtuple
/ dataclass
을 사용하는 모든 부분을 제어할 수 있는 상황이 아니라면, 명시적으로 새로운 class를 정의하는 편이 낫다.
언제 쓰지 말아야 해?
- dictionary를 이용하여 몇개의 key를 단순하게 관리할 수 있을 때
- 아래 단점들을 피하고 싶을 떄,
장점
- class 를 이용해서 data를 담아두면, type-safe 해진다. 그래서 프로그램 실행 중에 오류가 발생할 확률이 적어진다.
단점
- boiler-plate 문제가 있음
- id / name / brithdate / admin 이 반복됨
class User:
def __init__(
self, id: int, name: str, birthdate: date, admin: bool = False
) -> None:
self.id = id
self.name = name
self.birthdate = birthdate
self.admin = admin
__repr__()
메서드를 추가하여 필드 값이 모두 출력되도록 하지 않는 이상, instance를 출력할 때 field 값이 나타나지 않아서 불편함.
>>> user = User(id=1, name="Steve Jobs", birthdate=date(1955, 2, 24))
>>> user
<__main__.User object at 0x105558100>
>>> user1 = User(id=1, name="Steve Jobs", birthdate=date(1955, 2, 24))
>>> user2 = User(id=1, name="Steve Jobs", birthdate=date(1955, 2, 24))
>>> user1 == user2
False