튜플(tuple)은 인덱스를 통해서만 데이터에 접근할 수 있지만 네임드 튜플(named tuple)은 인덱스뿐만 아니라 키(key)로도 데이터에 접근할 수 있는 자료형이다.
collections.namedtuple()은 키값으로 데이터에 접근할 수 있는 튜플을 생성하는 함수이다.
문제
직원 주소록을 만들고자 다음과 같이 이름, 나이, 휴대전화로 구성된 직원 정보 데이터를 이용하려 한다.
data = [
('홍길동', 23, '01099990001'),
('김철수', 31, '01099991002'),
('이영희', 29, '01099992003'),
]
하지만, 리스트의 요소가 튜플이라 데이터에 접근하기가 쉽지 않다. 왜냐하면 데이터를 확인하려면 튜플 데이터의 인덱스 순서가 무엇을 뜻하는지 알아야 하기 때문이다.
이에 다음처럼 튜플 데이터를 각 칼럼의 이름으로 찾을 수 있도록 하려면 어떻게 해야 할까?
emp = data[0] # 첫번째 직원
print(emp.name) # "홍길동" 출력
print(emp.age) # 23 출력
print(emp.cellphone) # 01099990001 출력
풀이
키값으로 튜플 데이터에 접근하는 데는 다양한 방법이 있다. 일반적으로는 클래스를 이용하지만, 여기서는 가장 간단하게 해결할 수 있는 namedtuple 모듈을 사용해 보기로 한다.
먼저 다음과 같이 namedtuple 모듈을 불러온다(import).
>>> from collections import namedtuple
그리고는 다음과 같이 데이터를 선언하자.
>>> data = [
... ('홍길동', 23, '01099990001'),
... ('김철수', 31, '01099991002'),
... ('이영희', 29, '01099992003'),
... ]
선언한 데이터의 형식에 맞게 다음과 같이 namedtuple 자료형을 생성하자.
>>> Employee = namedtuple('Employee', 'name, age, cellphone')
namedtuple() 함수의 첫 번째 입력은 자료형 이름(type name)이다. 보통 namedtuple()로 생성하는 객체 이름과 같도록 한다. 여기서는 Employee로 했다. 뒤에 따라오는 쉼표로 구성된 문자열 'name, age, cellphone' 은 Employee의 속성이 된다.
그리고 선언한 data의 요소인 튜플을 다음과 같이 namedtuple로 변환하자.
>>> data = [Employee(emp[0], emp[1], emp[2]) for emp in data]
리스트 컴프리헨션을 이용하여 data의 각 튜플을 모두 Employee 자료형(네임드 튜플 자료형)으로 교체했다. Employee 자료형의 _make() 함수를 사용하면 이 과정을 더 깔끔하게 처리할 수 있다.
>>> data = [Employee._make(emp) for emp in data]
튜플의 요소가 많다면 _make() 함수를 사용하는 것이 유리하다. 이제 Employee 자료형으로 변경한 데이터를 다음과 같이 사용해 보자.
>>> emp = data[0] # 첫번째 직원
>>> emp.name
'홍길동'
>>> emp.age
23
>>> emp.cellphone
'01099990001'
이제 문제에서 요구하는 대로 인덱스가 아닌 키로 데이터를 조회할 수 있게 되었다. 참고로 네임드 튜플은 다음처럼 _asdict() 함수를 사용하면 간단하게 딕셔너리로 변환할 수 있다.
>>> emp._asdict()
{'name': '홍길동', 'age': 23, 'cellphone': '01099990001'}
또한, 네임드 튜플은 다음처럼 인덱스로 접근할 수도 있다.
>>> emp[0]
'홍길동'
>>> emp[1]
23
>>> emp[2]
'01099990001'
그리고 네임드 튜플은 값을 변경할 수 없는(immutable) 튜플의 특징을 그대로 가지므로 속성값을 변경하려고 하면 다음과 같은 오류가 발생한다.
>>> emp.name = '박길동'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
그러므로 다음처럼 _replace() 함수로만 값을 바꿀 수 있다.
>>> new_emp = emp._replace(name="박길동")
>>> new_emp
Employee(name='박길동', age=23, cellphone='01099990001')
단, _replace() 함수는 해당 객체를 직접 변경하는 것이 아니라 값을 변경한 새로운 객체를 만들어 반환한다는 점에 주의하자.
'Python > Python' 카테고리의 다른 글
pip install "패키지" 오류 발생 시 대처 (0) | 2022.12.26 |
---|---|
파이썬 - collections.Counter (0) | 2022.12.17 |
파이썬 - collections.deque (0) | 2022.12.17 |
파이썬 - datetime 라이브러리 (0) | 2022.12.17 |
파이썬 - 내장 함수 (0) | 2022.12.15 |