본문 바로가기

Programming👩🏻‍💻/Python

Packing, Unpacking

 

패킹/언패킹이 가능한 *iterable 자료형들

 

*iterable은 반복문으로 요소를 하나씩 순회할 수 있는 객체를 뜻한다.

__iter__() 메서드를 가지고 있어 이터레이터 객체를 반환하며 __next__() 메서드로 요소를 순차적으로 반환한다.

"반복할 수 있는" 데이터 모음

# 1. 리스트(List)
a, b, c = [1, 2, 3]

# 2. 튜플 (Tuple)
x, y, z = (4, 5, 6)

# 3. 문자열 (String), 글자당 인덱싱 가능
p, q, r = "abc"

# 4. 세트(Set)
i, j, k = {1, 2, 3}

# 5. 딕셔너리(Dictionary), 기본적으로 키가 언패킹됨
a, b, c = {"x":1, "y":2, "z":3} # a="x", b="y", c="z"

# 5.1 값(value)을 언패킹하는 경우에는 .values()
a, b, c = {"x":1, "y":2, "z":3}.values() # a=1, b=2, c=3

# 5.2 키-값 쌍을 모두 언패킹하고 싶다면 .items()
a, b, c = {"x":1, "y":2, "z":3}.items() 
# a=("x",1) b=("y",2) c=("z",3) 
# 딕셔너리 .items()는 키-값 쌍으로 '튜플'로 묶어 반환한다.


# 6. range
a, b, c = range(3) # a=0, b=1, c=2

# 7. zip
a, b = zip([1,2], [3,4]) # a=(1,3) b=(2,4)

# 8. map
a, b, c = map(int, ["1", "2", "3"])


# 모두 순회 가능

for item in [1, 2, 3]:
for item in (1, 2, 3):
for char in "hello":
for item in {1, 2, 3}:
for key in {"a":1, "b":2}:
for num in range(3):
for pair in zip([1,2], [3,4]):
for num in map(int, ["1","2"]):

 

패킹(Packing): 여러 개 값을 하나의 변수나 객체로 합쳐서 받을 수 있다.

 

*args(arguments): 여러 개의 인자를 튜플로 패킹.

# *args를 사용한 패킹
def func(*args):
      print(args) # (1, 2, 3)
      print(type(args)) # <class 'tuple'>

func(1, 2, 3)

# 리스트를 언패킹하여 개별 인수로 전달
my_list = [1, 2, 3]
my_function(*my_list)

 

 

 

**kwargs(keyword arguments): 키워드 인자들을 딕셔너리로 패킹

# 이름=값 형태의 키워드 인자를 딕셔너리로 받음
def example(**kwargs):
	print(kwargs) # {'name': "Nara", "age": 59}
    print(type(kwargs)) # <class 'dic'>
   
example(name="Nara", age=59) # 키워드 인수 전달 -> 딕셔너리 변환

info = {'name': "MuMu", 'age': 39}
example(**info) # 딕셔너리 인자 전달

 

 

 

언패킹(Unpacking): 묶여있는 값을 풀어서 여러 변수에 나눠 담는 것

# 리스트 언패킹
numbers = [1, 2, 3]
a, b, c = numbers # a=1, b=2, c=3

 

# 문자열 언패킹
string = "abc"
x, y, z = string # x='a', y='b', z='c'

 

# 단일 애스터리스크(*) 이용한 패킹
first, *rest = [1, 2, 3, 4, 5]
print(first) # 1
print(rest) # [2, 3, 4, 5]

 

# 함수 패킹
def sum_all(*arg):
	return sum(args)
    
print(sum_all(1, 2, 3)) # 6

# 함수 언패킹
def print_info(name, age, city):
	print(f"{name}는 {city}에 살고 {age}살입니다.")
    
info = ["김나나", 10, "미국"]
print_info(*info) # 리스트 언패킹해서 함수 호출

 

 

 

실무에서 사용할 법한 예시

 

1. 함수의 가변 인자 처리(패킹)

    """
    	언패킹 과정
    	name = "MoMo"
        age = 49
        email = "momo@docomo.hk"
        
        나머지 값들은(additional_info) 리스트로 패킹
        *additional_info = ["shizuoka", "BE-developer"] 
    """

def save_user_info(*args):
	name, age, email, *additional_info = args
    user = {
    	"name": name,
        "age": age,
        "email": email,
        "additional": addtional_info # 추가 정보는 리스트로 패킹
    }
    
    return user
    
  
  result = save_user_info("MoMo", 49, "momo@docomo.hk", "shizuoka", "BE-developer") 
  # *args로 튜플 패킹

 

 

2. 데이터베이스 결과 처리(언패킹)

# DB에서 가져온 user_data가 있다고 가정

user_data = ["meme", "meme@yahoo.kr", "jejudo"]

# 언패킹으로 깔끔하게 할당
name, email, address = user_data

 

 

3. 딕셔너리 처리(딕셔너리 언패킹)

def update_user(**user_info): 
	default_info = {
    	"age": 98,
        "country": "Korea"
    }
    
    # 딕셔너리 언패킹으로 기본값과 새로운 정보 합치기
    return {**default_info, **user_info} # 하나의 딕셔너리로 합쳐짐
    # retun(default_info, user_info) # 두개의 딕셔너리 요소가 있는 튜플로 반환됨
    
 # 사용 예시
 result = update_user(name="ruru", age=20) #키인자 전달
 print(result) 
 # 출력: {"age": 20, "country": "Korea", "name": "ruru"}

 

 

4. 리스트 분할 (부분 언패킹)

# 게시판 최근 게시물 중 첫 게시물과 나머지 처리

posts = ["오늘 날씨", "운동 해야하는데", "공부는 어렵다", "자고싶어"]

# 첫 게시물과 나머지 분리
lastest, *others = posts

print(f"최근 게시물:{lastest}") 
# 최근 게시물: 오늘 날씨
print(f"나머지 게시물: {others}") 
# 나머지 게시물: ["운동 해야하는데", "공부는 어렵다", "자고싶어"]

 

 

5. 데이터 변환 (여러 값 언패킹)

# csv 데이터 처리 가정

rows = [
	"riri,15,TYO",
    	"mimi,20,OSA",
    	"haru,44,SEL"
]


users = [] # 사용자 정보 저장할 빈 리스트 초기화

for row in rows:
	name, age, city = row.split(',') 
    # 쉼표로 구분하여 이름/나이/도시 분리 언패킹
    
    users.append)[ 
    	'name': name,
        'age': int(age), # 문자열 정수 변환
        'city': ciry
    ])
    # 분리된 정보를 딕셔너리 형태로 저장하여 users 리스트에 추가

 

 

6. API 응답 처리

api_response = {
	"user": {
    	"name": "kimi",
        "contacts":['010-222-3333', '031-234-3333']
    }
}

name = api_response["user"]["name"] 
# user key로 접근하여 "name" 값을 추출 = "kimi"

primary_contact, *other_contacts = api_response["user"]["contacts"]
# 첫번째 요소를 대표 연락처, 나머지 others_contact에 할당