[python] namedTuple

728x90

1. namedTuple이란?

네임드 튜플은 튜플형식이지만 일반 튜플과 달리 key와 value로 이루어져있습니다. 따라서 인덱스뿐만 아니라 key값으로도 호출이 가능합니다. 따라서 튜플의 불변성과 딕셔너리의 유연성을 결합하여 사용할 수 있는 함수입니다.

 

2. 선언방법

네임드 튜플의 선언방식에는 4가지 정도가 있습니다.

아래 예제에서는 두개의 key를 생성했지만 띄어쓰기나, 콤마를 사용하여 더 많이 생성 가능합니다.

 

# namedTuple 선언 첫번째 방법
Point = namedtuple('Point','x y') # typename = Point, key는 x,y -> key는 띄어쓰기로 여러개 선언 가능하다.

# namedTuple 선언 두번째 방법
Point2 = namedtuple('Point',['x','y'])

# namedTuple 선언 세번째 방법
Point3 = namedtuple('Point','x,y') # 콤마로 key를 구분

# namedTuple 선언 네번째 방법
Point4 = namedtuple('Point','x y x class',rename=True) #default = False -> class는 예약어라서 에러발생, rename = True일때는 예약어 사용도 가능

 

주의해야할 점은 네임드 튜플로 생성된 클래스로 인스턴스를 만들 때 매개변수를 넣을때는 key의 개수에 맞게 넣어야 합니다.

Point = namedtuple('Point','x y')

p1 = Point(10,20)
p11 = Point(10,20,30) #TypeError: <lambda>() takes 3 positional arguments but 4 were given

 

인스턴스를 생성한 후 호출방식은 인덱스로도 가능하며 key로도 가능합니다.

Point2 = namedtuple('Point',['x','y'])

p2 = Point2(x=10,y=35) # key는 있어도 되고 없어도 된다.
# p2 = Point2(10,35) 도 위와 동일

print(p2) #출력: Point(x=10, y=35)

print(p2.x) #출력: 10
print(p2[0]) #출력: 10
print(p2.y) #출력: 35
print(p2[1]) #출력: 35

3. 일반 튜플과의 비교

일반 튜플을 사용한 두 점 사이의 거리계산

pt1 = (1.0,5.0)
pt2 = (2.5,1.5)

from math import sqrt

leng1 = sqrt((pt1[0] - pt2[0])**2 + (pt1[1]-pt2[1])**2)

print("leng1:",leng1) #출력:leng1: 3.8078865529319543

 

네임드 튜플을 사용한 두 점 사이의 거리계산

from collections import namedtuple 

Point = namedtuple('Point','x y') 

pt3 = Point(1.0,5.0)
pt4 = Point(2.5,1.5)

print(type(pt3),pt3,type(pt4),pt4) #출력: <class '__main__.Point'> Point(x=1.0, y=5.0) <class '__main__.Point'> Point(x=2.5, y=1.5)
print(pt3.x,pt3.y) #출력:1.0 5.0
leng2 = sqrt((pt3.x - pt4.x)**2 + (pt3.y-pt4.y)**2)
print("leng2",leng2) #출력: leng2 3.8078865529319543

 

결과값을 동일하게 나오지만 일반 튜플과 다르게 명확하게 x,y를 지정하여 호출하므로 더 알아보기 쉽습니다.

4. 언팩킹

Point3 = namedtuple('Point','x,y') 

#dict -> tuple 언팩킹
temp_dict = {'x':70,'y':30}

p5 = Point3(**temp_dict) # dict앞에 **을 붙이면 알아서 변수명을 찾아간다 : dict -> tuple
print(p5) #출력: Point(x=70, y=30)

 

5. 네임드 튜플 메서드

Point = namedtuple('Point','x y')

temp_list = [50,60]

# _make() : 새로운 객체 생성
p6 = Point._make(temp_list)
print(p6) #출력:Point(x=50, y=60)

# _fields : 필드 네임확인 -> key값만 확인
print(p6._fields) #출력:('x', 'y')

# _asdict() : dict형 반환 -> 파이썬 3.8부터 OrderedDict이 아닌 일반 dict을 반환
print(p6._asdict()) #출력: {'x': 50, 'y': 60}

 

6. 데이터 실습 예제

# 실습 예제
# 반 20명, 4개의 반(A,B,C,D)
Classes = namedtuple('Classes',['rank','number'])

# 그룹 리스트 선언
numbers = [str(n) for n in range(1,21)]
ranks = 'A B C D'.split()

print(numbers) #출력: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20']
print(ranks) #출력: ['A', 'B', 'C', 'D']

# 리스트 컴프리헨션
students = [Classes(rank,number) for rank in ranks for number in numbers]
print(len(students)) #출력: 80
print()
print(students)
# 출력:[Classes(rank='A', number='1'), Classes(rank='A', number='2'), Classes(rank='A', number='3'), Classes(rank='A', number='4'), Classes(rank='A', number='5'), Classes(rank='A', number='6'), Classes(rank='A', number='7'), Classes(ra
# nk='A', number='8'), Classes(rank='A', number='9'), Classes(rank='A', number='10'), Classes(rank='A', number='11'), Classes(rank='A', number='12'), Classes(rank='A', number='13'), Classes(rank='A', number='14'), Classes(rank='A'
# , number='15'), Classes(rank='A', number='16'), Classes(rank='A', number='17'), Classes(rank='A', number='18'), Classes(rank='A', number='19'), Classes(rank='A', number='20'), Classes(rank='B', number='1'), Classes(rank='B', num
# ber='2'), Classes(rank='B', number='3'), Classes(rank='B', number='4'), Classes(rank='B', number='5'), Classes(rank='B', number='6'), Classes(rank='B', number='7'), Classes(rank='B', number='8'), Classes(rank='B', number='9'), C
# lasses(rank='B', number='10'), Classes(rank='B', number='11'), Classes(rank='B', number='12'), Classes(rank='B', number='13'), Classes(rank='B', number='14'), Classes(rank='B', number='15'), Classes(rank='B', number='16'), Class
# es(rank='B', number='17'), Classes(rank='B', number='18'), Classes(rank='B', number='19'), Classes(rank='B', number='20'), Classes(rank='C', number='1'), Classes(rank='C', number='2'), Classes(rank='C', number='3'), Classes(rank
# ='C', number='4'), Classes(rank='C', number='5'), Classes(rank='C', number='6'), Classes(rank='C', number='7'), Classes(rank='C', number='8'), Classes(rank='C', number='9'), Classes(rank='C', number='10'), Classes(rank='C', numb
# er='11'), Classes(rank='C', number='12'), Classes(rank='C', number='13'), Classes(rank='C', number='14'), Classes(rank='C', number='15'), Classes(rank='C', number='16'), Classes(rank='C', number='17'), Classes(rank='C', number='
# 18'), Classes(rank='C', number='19'), Classes(rank='C', number='20'), Classes(rank='D', number='1'), Classes(rank='D', number='2'), Classes(rank='D', number='3'), Classes(rank='D', number='4'), Classes(rank='D', number='5'), Cla
# sses(rank='D', number='6'), Classes(rank='D', number='7'), Classes(rank='D', number='8'), Classes(rank='D', number='9'), Classes(rank='D', number='10'), Classes(rank='D', number='11'), Classes(rank='D', number='12'), Classes(ran
# k='D', number='13'), Classes(rank='D', number='14'), Classes(rank='D', number='15'), Classes(rank='D', number='16'), Classes(rank='D', number='17'), Classes(rank='D', number='18'), Classes(rank='D', number='19'), Classes(rank='D
# ', number='20')]

students2 = [Classes(rank,number)
             for rank in 'A B C D'.split()
             for number in [str(n) for n in range(1,21)]]

print(len(students2)) #출력:80

print(students2) # students 와 동일
#출력:[Classes(rank='A', number='1'), Classes(rank='A', number='2'), Classes(rank='A', number='3'), Classes(rank='A', number='4'), Classes(rank='A', number='5'), Classes(rank='A', number='6'), Classes(rank='A', number='7'), Classes(ra
# nk='A', number='8'), Classes(rank='A', number='9'), Classes(rank='A', number='10'), Classes(rank='A', number='11'), Classes(rank='A', number='12'), Classes(rank='A', number='13'), Classes(rank='A', number='14'), Classes(rank='A'
# , number='15'), Classes(rank='A', number='16'), Classes(rank='A', number='17'), Classes(rank='A', number='18'), Classes(rank='A', number='19'), Classes(rank='A', number='20'), Classes(rank='B', number='1'), Classes(rank='B', num
# ber='2'), Classes(rank='B', number='3'), Classes(rank='B', number='4'), Classes(rank='B', number='5'), Classes(rank='B', number='6'), Classes(rank='B', number='7'), Classes(rank='B', number='8'), Classes(rank='B', number='9'), C
# lasses(rank='B', number='10'), Classes(rank='B', number='11'), Classes(rank='B', number='12'), Classes(rank='B', number='13'), Classes(rank='B', number='14'), Classes(rank='B', number='15'), Classes(rank='B', number='16'), Class
# es(rank='B', number='17'), Classes(rank='B', number='18'), Classes(rank='B', number='19'), Classes(rank='B', number='20'), Classes(rank='C', number='1'), Classes(rank='C', number='2'), Classes(rank='C', number='3'), Classes(rank
# ='C', number='4'), Classes(rank='C', number='5'), Classes(rank='C', number='6'), Classes(rank='C', number='7'), Classes(rank='C', number='8'), Classes(rank='C', number='9'), Classes(rank='C', number='10'), Classes(rank='C', numb
# er='11'), Classes(rank='C', number='12'), Classes(rank='C', number='13'), Classes(rank='C', number='14'), Classes(rank='C', number='15'), Classes(rank='C', number='16'), Classes(rank='C', number='17'), Classes(rank='C', number='
# 18'), Classes(rank='C', number='19'), Classes(rank='C', number='20'), Classes(rank='D', number='1'), Classes(rank='D', number='2'), Classes(rank='D', number='3'), Classes(rank='D', number='4'), Classes(rank='D', number='5'), Cla
# sses(rank='D', number='6'), Classes(rank='D', number='7'), Classes(rank='D', number='8'), Classes(rank='D', number='9'), Classes(rank='D', number='10'), Classes(rank='D', number='11'), Classes(rank='D', number='12'), Classes(ran
# k='D', number='13'), Classes(rank='D', number='14'), Classes(rank='D', number='15'), Classes(rank='D', number='16'), Classes(rank='D', number='17'), Classes(rank='D', number='18'), Classes(rank='D', number='19'), Classes(rank='D
# ', number='20')]


for s in students:
    print(s)

#출력:
# Classes(rank='A', number='1')
# Classes(rank='A', number='2')
# Classes(rank='A', number='3')
# Classes(rank='A', number='4')
# Classes(rank='A', number='5')
# Classes(rank='A', number='6')
# Classes(rank='A', number='7')
# Classes(rank='A', number='8')
# Classes(rank='A', number='9')
# Classes(rank='A', number='10')
# Classes(rank='A', number='11')
# Classes(rank='A', number='12')
# Classes(rank='A', number='13')
# Classes(rank='A', number='14')
# Classes(rank='A', number='15')
# Classes(rank='A', number='16')
# Classes(rank='A', number='17')
# Classes(rank='A', number='18')
# Classes(rank='A', number='19')
# Classes(rank='A', number='20')
# Classes(rank='B', number='1')
# Classes(rank='B', number='2')
# Classes(rank='B', number='3')
# Classes(rank='B', number='4')
# Classes(rank='B', number='5')
# Classes(rank='B', number='6')
# Classes(rank='B', number='7')
# Classes(rank='B', number='8')
# Classes(rank='B', number='9')
# Classes(rank='B', number='10')
# Classes(rank='B', number='11')
# Classes(rank='B', number='12')
# Classes(rank='B', number='13')
# Classes(rank='B', number='14')
# Classes(rank='B', number='15')
# Classes(rank='B', number='16')
# Classes(rank='B', number='17')
# Classes(rank='B', number='18')
# Classes(rank='B', number='19')
# Classes(rank='B', number='20')
# Classes(rank='C', number='1')
# Classes(rank='C', number='2')
# Classes(rank='C', number='3')
# Classes(rank='C', number='4')
# Classes(rank='C', number='5')
# Classes(rank='C', number='6')
# Classes(rank='C', number='7')
# Classes(rank='C', number='8')
# Classes(rank='C', number='9')
# Classes(rank='C', number='10')
# Classes(rank='C', number='11')
# Classes(rank='C', number='12')
# Classes(rank='C', number='13')
# Classes(rank='C', number='14')
# Classes(rank='C', number='15')
# Classes(rank='C', number='16')
# Classes(rank='C', number='17')
# Classes(rank='C', number='18')
# Classes(rank='C', number='19')
# Classes(rank='C', number='20')
# Classes(rank='D', number='1')
# Classes(rank='D', number='2')
# Classes(rank='D', number='3')
# Classes(rank='D', number='4')
# Classes(rank='D', number='5')
# Classes(rank='D', number='6')
# Classes(rank='D', number='7')
# Classes(rank='D', number='8')
# Classes(rank='D', number='9')
# Classes(rank='D', number='10')
# Classes(rank='D', number='11')
# Classes(rank='D', number='12')
# Classes(rank='D', number='13')
# Classes(rank='D', number='14')
# Classes(rank='D', number='15')
# Classes(rank='D', number='16')
# Classes(rank='D', number='17')
# Classes(rank='D', number='18')
# Classes(rank='D', number='19')
# Classes(rank='D', number='20')