TIL10. Python : NamedTuple μ΄λž€?

ID짱재·2021λ…„ 9μ›” 10일
0

Python

λͺ©λ‘ 보기
22/39
post-thumbnail

πŸ“Œ 이 ν¬μŠ€νŒ…μ—μ„œλŠ” Python의 NamedTuple을 μ‚¬μš©ν•˜λŠ” μ΄μœ μ™€ μ‚¬μš© 방법에 λŒ€ν•΄ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.



🌈 NamedTuple

πŸ”₯ namedtuple을 μ™œ μ“ΈκΉŒμš”?

πŸ”₯ namedtuple μ–΄λ–»κ²Œ μ‚¬μš©ν• κΉŒ?

πŸ”₯ namedtuple의 λ§€μ„œλ“œ 정리

πŸ”₯ namedtuple ν™œμš© μ˜ˆμ‹œ



1. namedTuple을 μ™œ μ‚¬μš©ν•˜λŠ”κ°€?

πŸ€” namedTuple μ΄λž€?

βœ”οΈ λ„€μž„λ“œνŠœν”Œμ€ 객체의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜ 듯이 νŠœν”Œμ„ μƒμ„±ν•˜μ—¬ 각 μ›μ†Œμ— μ΄λ¦„μœΌλ‘œ 접근이 κ°€λŠ₯ν•œ νŠœν”Œμ„ μ˜λ―Έν•©λ‹ˆλ‹€.
βœ”οΈ 즉, λ°μ΄ν„°μ˜ 값을 μˆ˜μ •ν•  ν•„μš”κ°€ μ—†λ‹€λ©΄ νŠœν”Œμ˜ 값에 μ΄λ¦„μœΌλ‘œ μ ‘κ·Όν•  수 있기 λ•Œλ¬Έμ— 일반 νŠœν”Œμ΄ 인덱슀둜 μ ‘κ·Όν•˜λŠ” 것에 λΉ„ν•΄ μ§κ΄€μ μž…λ‹ˆλ‹€.
βœ”οΈ λ˜ν•œ λ„€μž„λ“œνŠœν”Œμ€ 일반 객체 ν˜•νƒœλ³΄λ‹€ 적은 λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜κ³ , λ‹€μ–‘ν•œ 접근법을 μ§€μ›ν•©λ‹ˆλ‹€.
βœ”οΈ λ©”λͺ¨λ¦¬ νš¨μœ¨μ„± 일반적인 μƒν™©μ—μ„œ λ¦¬μŠ€νŠΈλ³΄λ‹€ νŠœν”Œμ΄ μ’‹κ³ , νŠœν”Œλ³΄λ‹€ λ„€μž„λ“œνŠœν”Œμ΄ μ’‹μŠ΅λ‹ˆλ‹€.

πŸ€” 두 점 μ‚¬μ΄μ˜ 거리 κ΅¬ν•˜κΈ° 문제

βœ”οΈ 두 점 μ‚¬μ΄μ˜ 거리λ₯Ό κ΅¬ν•˜λŠ” 곡식을 예둜 λ“€μ–΄, μΌλ°˜νŠœν”Œκ³Ό λ„€μž„λ“œνŠœν”Œμ˜ 차이λ₯Ό μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€. 두 점 μ‚¬μ΄μ˜ κ±°λ¦¬λŠ” μ•„λž˜ 곡식을 μ‚¬μš©ν•˜μ—¬ ꡬ할 수 μžˆμŠ΅λ‹ˆλ‹€.

βœ”οΈ 일반 νŠœν”Œμ€ 인덱슀 번호둜 값에 μ ‘κ·Όν•  수 있기 λ•Œλ¬Έμ— 값을 μ§κ΄€μ μœΌλ‘œ μ΄ν•΄ν•˜κΈ° μ–΄λ €μ›Œ 값을 μ™Έμš°κ³  μžˆμ–΄μ•Όν•˜κ±°λ‚˜, 주석이 ν•„μš”ν•©λ‹ˆλ‹€.

from math import sqrt
point1 = (1.0, 5.0) # x1=1.0, y1=5.0
point2 = (2.5, 1.5) # x2=2.5, y2=1.5
line_len = sqrt((point2[0]-point1[0]) ** 2 + (point2[1]-point1[1]) ** 2)
print(line_len) # 3.8078865529319543

βœ”οΈ 이에 λ°˜ν•΄, namedtuple을 μ‚¬μš©ν•˜λ©΄ 각 λ³€μˆ˜κ°€ κ°€λ₯΄ν‚€λŠ” 값을 보닀 μ§κ΄€μ μœΌλ‘œ μ ‘κ·Όν•˜κ³  ν™œμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
βœ”οΈ namedtuple은 μ΄λ¦„μ—μ„œ μ•Œ 수 μžˆλ“―μ΄ λ„€μž„λ“œνŠœν”Œμ€ 이름을 가진 tuple을 μ˜λ―Έν•˜κΈ° λ•Œλ¬Έμ— tuple의 각 μš”μ†Œμ— λ ˆμ΄λΈ”μ„ 쀄 수 μžˆμŠ΅λ‹ˆλ‹€.
βœ”οΈ λ„€μž„λ“œνŠœν”Œμ€ λ‹€μ–‘ν•œ 데이터 νƒ€μž…μ„ μ§€μ›ν•˜λŠ” collections 내에 μ‘΄μž¬ν•˜κ³ , 객체처럼 μƒμ„±ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

from math import sqrt
from collections import namedtuple # πŸ‘ˆ "namedtuple" import
Point = namedtuple('Point', 'x y') # πŸ‘ˆ namedtuple μ„ μ–Έ
point1 = Point(1.0, 5.0)
point2 = Point(2.5, 1.5)
line_len = sqrt((point2.x-point1.x) ** 2 + (point2.y-point1.y) ** 2)
print(line_len) # 3.8078865529319543


2. namedtuple μ–΄λ–»κ²Œ μ‚¬μš©ν• κΉŒ?

πŸ€” nametuple μ„ μ–Έ 방법

βœ”οΈ 리슀트 ν˜•νƒœλ‘œ λ³€μˆ˜ μ„ μ–Έ : πŸ” Point1 = namedtuple('Point', ['x', 'y'])
βœ”οΈ 콀마 μ‚½μž…μœΌλ‘œ μ„ μ–Έ : πŸ” Point2 = namedtuple('Point', 'x, y')
βœ”οΈ 띄어쓰기 μ‚½μž…μœΌλ‘œ μ„ μ–Έ : πŸ” Point3 = namedtuple('Point', 'x y')
βœ”οΈ rename μ˜΅μ…˜ μ‚¬μš© : πŸ” Point4 = namedtuple('Point', 'x y x class', rename=True)

# λ„€μž„λ“œ νŠœν”Œ μ„ μ–Έ 방법
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μž„
print(Point1, Point2, Point3, Point4) # <class '__main__.Point'> <class '__main__.Point'> <class '__main__.Point'> <class '__main__.Point'>

πŸ€” rename μ˜΅μ…˜μ΄λž€?

βœ”οΈ namedTuple λ˜ν•œ tuple처럼 λΆˆλ³€μ˜ νŠΉμ„±μ„ μ§€λ‹ˆκ³  있기 λ•Œλ¬Έμ— 쀑볡될 수 μ—†κ³ , λ‹Ήμ—°νžˆ "class"와 같은 μ˜ˆμ•½μ–΄ 듀은 μΈμŠ€ν„΄μŠ€ λ³€μˆ˜μ²˜λŸΌ 지정할 수 μ—†μŠ΅λ‹ˆλ‹€.
βœ”οΈ λ”°λΌμ„œ μ•„λž˜μ™€ 같은 codeλŠ” x값이 μ€‘λ³΅λ˜μ–΄ 있고, classλΌλŠ” μ˜ˆμ•½μ–΄κ°€ μ„ μ–Έ μ‹œ μ‚¬μš©λ˜μ—ˆκΈ° λ•Œλ¬Έμ— μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚΅λ‹ˆλ‹€.

  • πŸ”Ž Point4 = namedtuple('Point', 'x y x class') πŸ‘ˆ x쀑볡, class μ˜ˆμ•½μ–΄

βœ”οΈ 이럴 경우, rename μ˜΅μ…˜μ„ True둜 ν™œμ„±ν™”ν•˜λ©΄ μ€‘λ³΅λ˜λŠ” κ°’ λ˜λŠ” μ˜ˆμ•½μ–΄ λ“±μ˜ 잘λͺ»λœ λ³€μˆ˜λ‘œ μ„ μ–Έ μ‹œ μ‚¬μš©ν•΄λ„ 였λ₯˜λ₯Ό λ°˜ν™˜ν•˜μ§€ μ•Šκ³ , λžœλ€ν•œ λ³€μˆ˜μ— 데이터λ₯Ό ν• λ‹Ήν•΄μ€λ‹ˆλ‹€.
βœ”οΈ λΏλ§Œμ•„λ‹ˆλΌ λ”λΈ”μ•„μŠ€νƒ€(**)λ₯Ό μ‚¬μš©ν•΄ λ”•μ…”λ„ˆλ¦¬μ˜ ν˜•νƒœλ„ μ–ΈνŒ©ν‚Ή ν•΄μ€λ‹ˆλ‹€.

# λ„€μž„λ“œ νŠœν”Œ μ„ μ–Έ 방법
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μž…λ‹ˆλ‹€.
p1 = Point1(x=10, y=35)
print(p1) # Point(x=10, y=35)
p2 = Point2(20, 40)
print(p2) # Point(x=20, y=40)
p3 = Point3(45, y=20)
print(p3) # Point(x=45, y=20)
p4 = Point4(10, 20, 30, 40)
print(p4) # Point(x=10, y=20, _2=30, _3=40) πŸ‘ˆ μžλ™μœΌλ‘œ renameν•΄μ€λ‹ˆλ‹€:)
# λ”•μ…”λ„ˆλ¦¬ μ–ΈνŒ©ν‚Ή
temp_dict = {'x':75, 'y':55} 
p5 = Point1(**temp_dict) # πŸ‘ˆ λ”•μ…”λ„ˆλ¦¬ μ–ΈνŒ©ν‚Ή
print(p5) # Point(x=75, y=55)
# unpacking ν™œμš©
x, y = p3
print(x+y) # 65


3. namedtuple의 λ§€μ„œλ“œ 정리

πŸ€” _make() : μƒˆλ‘œμš΄ 객체 생성

Point1 = namedtuple('Point', ['x', 'y'])
temp = [52, 38]
p4 = Point1._make(temp)
print(p4) # Point(x=52, y=38)

πŸ€” _fields() : ν•„λ“œ λ„€μž„ 확인

Point1 = namedtuple('Point', ['x', 'y'])
Point2 = namedtuple('Point', 'x, y')
Point3 = namedtuple('Point', 'x y')
print(p1._fields, p2._fields, p3._fields,) # ('x', 'y') ('x', 'y') ('x', 'y')

πŸ€” _asdict() : λ”•μ…”λ„ˆλ¦¬λ‘œ λ³€ν™˜

Point1 = namedtuple('Point', ['x', 'y'])
p1 = Point1(x=10, y=35)
temp = [52, 38]
p4 = Point1._make(temp)
print(p1._asdict(), p4._asdict()) # {'x': 10, 'y': 35} {'x': 52, 'y': 38}
print(type(p1._asdict()), type(p4._asdict())) # <class 'dict'> <class 'dict'>

πŸ€” _replace() : λ„€μž„λ“œνŠœν”Œ λ˜ν•œ λΆˆλ³€μ΄κΈ° λ•Œλ¬Έμ—, 값을 μˆ˜μ •ν•˜μ§€ λͺ»ν•©λ‹ˆλ‹€. 이에 μˆ˜μ •λœ "μƒˆλ‘œμš΄" 객체 λ°˜ν™˜ν•©λ‹ˆλ‹€.

Point2 = namedtuple('Point', 'x, y')
p2 = Point2(20, 40)
print(p2) # Point(x=20, y=40)
print(p2._replace(y=100)) # Point(x=20, y=100)


4. namedtuple ν™œμš© μ˜ˆμ‹œ

πŸ€” ν•™κΈ‰ ꡬ성은 λ§Œλ“€μ–΄ λ΄…μ‹œλ‹€!

βœ”οΈ 4개의 반(A,B,C,D)에 각 20λͺ…μ˜ 학생이 μžˆμ„ λ•Œ 학생 전체 κ·Έλ£Ή 생성
βœ”οΈ 1λ²ˆλΆ€ν„° 20λ²ˆκΉŒμ§€ 학생 생성 : πŸ” numbers = [str(n) for n in range(1,21)]
βœ”οΈ 4개의 반 생성 : πŸ” ranks = 'A B C D'.split()

# 4개의 λ°˜μ— A,B,C,D의 각 20λͺ…μ˜ 학생이 μžˆμ„ λ•Œ 학생 전체 κ·Έλ£Ή 생성
from collections import namedtuple
numbers = [str(n) for n in range(1,21)] # ['1', '2', '3', '4', ...... '17', '18', '19', '20']
ranks = 'A B C D'.split() # ['A', 'B', 'C', 'D']
Classes = namedtuple('Classes', ['rank', 'number']) # 객체λͺ…(classes)κ³Ό λ³€μˆ˜λͺ…(classes)을 μΌμΉ˜μ‹œν‚€λŠ”κ²Œ κ΄€λ‘€μž„
students = [Classes(rank, number) for rank in ranks for number in numbers]
print(len(students)) # 80
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(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')]
"""
profile
Keep Going, Keep Coding!

0개의 λŒ“κΈ€