Python/Intermediate

[Python] NamedTuple - Magic Method(3)

unsungIT 2021. 5. 21. 22:53

일반적인 tuple과 namedtupel 사용방법

  • 일반적인 tuple 사용시, 인덱스로 접근하므로 오류 가능성이 높고, 직관적이지 않다
# 일반적인 튜플 사용
from math import sqrt
pt1 = (1.0, 5.0)  # 변수 개수를 제한하는 구조로 설계불가. 네임드 튜플과 차이임.
pt2 = (2.5, 1.5)

l_leng1 = sqrt((pt2[0] - pt1[0]) ** 2 + (pt2[1] - pt1[1]) ** 2)
print(l_leng1)
# 3.8078865529319543


# 네임드 튜플 사용
from collections import namedtuple

# 네임드 튜플 선언, 변수의 개수가 정해지므로 값을 3개 넣을수 없음
Point = namedtuple('Point', 'x y')

# 두 점 선언
pt3 = Point(1.0, 5.0) # Point(1.0, 5.0, 6.0) <<- 오류 발생함.
pt4 = Point(2.5, 1.5)
print(pt1)
print(pt2)
print(pt3)
print(pt4)

# 출력값을 보면 일반 튜플과 네임드 튜플의 차이를 알수 있다.
# (1.0, 5.0)
# (2.5, 1.5)
# Point(x=1.0, y=5.0)
# Point(x=2.5, y=1.5)

# 변수에 접근 방법
print(pt1[0])
print(pt3[0], pt3.y)
# 1.0       <- 인덱스로만 접근 가능, 직관적이지 않음
# 1.0 5.0   <- 인덱스도 가능하고 추가로 키값으로도 접근이 가능

# 계산
l_leng2 = sqrt((pt4.x - pt3.x) ** 2 + (pt4.y - pt3.y) ** 2)

# 출력
print(l_leng1)
print(l_leng2)
print(l_leng1 == l_leng2)
# 3.8078865529319543
# 3.8078865529319543
# True

 

 

Namedtuple 선언 방법 - 4가지 방법이 있음

 

Point1 = namedtuple('Point', ['x', 'y'])
Point2 = namedtuple('Point', 'x, y')
Point3 = namedtuple('Point', 'x y')
Point4 = namedtuple('Point', 'x y x class', rename=True) # Default=False, 이렇게 하면 중복된 키도 허용되고, class 같은 예약어도 허용된다.

# 출력
print(Point1, Point2, Point3, Point4)
# <class '__main__.Point'> <class '__main__.Point'> <class '__main__.Point'> <class '__main__.Point'>

 

 

객체 생성 및 접근방법

 

# Dict to Unpacking
temp_dict = {'x': 75, 'y': 55}

# 객체 생성
p1 = Point1(x=10, y=35)
p2 = Point2(20, 40)
p3 = Point3(45, y=20)
p4 = Point4(10, 20, 30, 40)
p5 = Point3(**temp_dict)     # dict type un-packing, * 1 개면 튜플 or 리스트.

# 출력
print(p1, p2, p3, p4, p5)
print(temp_dict)
print(*temp_dict)
# Point(x=10, y=35) Point(x=20, y=40) Point(x=45, y=20) Point(x=10, y=20, _2=30, _3=40) Point(x=75, y=55)
# {'x': 75, 'y': 55}
# x y

# 사용
print(p1[0] + p2[1]) # Index Error 주의
print(p1.x + p2.y) # 클래스 변수 접근 방식
# 50
# 50

# Unpacking
x, y = p3

print(x, y)
# 45 20

# # Rename 테스트
print(p4)
# Point(x=10, y=20, _2=30, _3=40)

 

 

_make() 를 이용한 개체 생성(리스트 -> 네임드 튜플)

 

# 네임드 튜플 메소드, 리스트로 객체 생성
temp = [52, 38]

# _make() : 새로운 객체 생성
p6 = Point1._make(temp)

print(p6)
print(*temp)
print(Point1(*temp)) # _make()를 사용하는것과 동일한 효과, list unpacking.
# Point(x=52, y=38)
# 52 38
# Point(x=52, y=38)

# _fields : 필드 네임 확인
print(p1._fields, p2._fields, p3._fields, p4._fields)
# ('x', 'y') ('x', 'y') ('x', 'y') ('x', 'y', '_2', '_3')

# _asdict() : OrderedDict 반환
print(p1._asdict(), p6._asdict())
# {'x': 10, 'y': 35} {'x': 52, 'y': 38}

 

 

실습

 

# 실 사용 실습
# 반20명 , 4개의 반-> (A,B,C,D) 번호

# 네임드 튜플 선언
Classes = namedtuple('Classes', ['rank', 'number'])

# 그룹 리스트 선언
numbers = [str(n) for n in range(1, 6)] # 출력시 데이터가 너무 많아서 줄임.
ranks = 'A B C D'.split()

# List Comprehension
students = [Classes(rank, number) for rank in ranks for number in numbers]

print(len(students))
print(students)
# 데이터가 많아서 출력 생략.


# 추천
students2 = [Classes(rank, number)
                    for rank in 'A B C D'.split()
                        for number in [str(n)
                            for n in range(1,6)]] # 출력시 데이터가 많아서 5개반으로 줄임.
                            
print(len(students2))
print(students2)
# 데이터가 많아서 출력 생략.


# 출력
for s in students:
    print(s)
# 데이터가 많아서 출력 생략.

print(students==students2)
# True

 

 

 

 

[그외 자료]

https://velog.io/@hyeseong-dev/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%84%A4%EC%9E%84%EB%93%9C%ED%8A%9C%ED%94%8C-tutorial

 

[Python] 네임드튜플 tutorial

파이썬의 네임드튜플은 인덱스와 네임드 속성을가지고 값에 접근하는 immutable 컨테이너 유형이에요. 특징이 이름 그대로 튜플의 특징과 추가적 특징을 짬봉한거라고 보면되요. 그리고 이녀석은

velog.io

 

https://blog.naver.com/wideeyed/221682049802

 

[Python] 네임드튜플(namedtuple) 소개 및 예제

알면 유용한 네임드 튜플(named tuple)에 대해서 예제를 통해 알아보겠습니다. 튜플(tuple)은 인덱스를 통...

blog.naver.com