Python 함수에서는 여러 개의 값을 하나씩 전달하는 것뿐만 아니라, 리스트나 튜플에 담긴 값을 함수의 여러 매개변수에 나누어 전달할 수도 있습니다.
이때 사용하는 것이 파라미터 언패킹(Parameter Unpacking)입니다.
언패킹은 말 그대로 하나로 묶여 있는 값을 풀어서 각각의 위치에 전달하는 것을 의미합니다. Python에서는 *와 ** 연산자를 사용해 시퀀스나 딕셔너리의 값을 함수에 전달할 수 있습니다.
이번 글에서는 함수 호출을 기준으로 *와 **를 사용하는 파라미터 언패킹을 알아보겠습니다.
파라미터 언패킹이란?
먼저 일반적인 함수 호출을 살펴보겠습니다.
def add(a, b, c):
return a + b + c
각 매개변수에 값을 직접 전달할 수 있습니다.
result = add(10, 20, 30)
print(result)
결과:
60
그런데 전달할 값이 리스트에 들어 있다면 어떻게 해야 할까요?
numbers = [10, 20, 30]
리스트 자체를 전달하면 a, b, c에 각각 들어가는 것이 아니라 리스트 하나가 하나의 인자로 전달됩니다.
이때 *를 사용하면 리스트의 값을 각각의 위치 인자로 풀어서 전달할 수 있습니다.
numbers = [10, 20, 30]
result = add(*numbers)
print(result)
결과:
60
*numbers가 [10, 20, 30]을 10, 20, 30으로 풀어서 함수에 전달하는 것입니다.
리스트와 튜플 언패킹
*를 사용한 언패킹은 리스트뿐만 아니라 튜플과 같은 반복 가능한 객체에도 사용할 수 있습니다.
def introduce(name, age, major):
print(name, age, major)
튜플을 준비합니다.
student = ("철수", 20, "Python")
그리고 *를 사용해 전달합니다.
introduce(*student)
실제로는 다음과 같은 호출과 같은 의미입니다.
introduce("철수", 20, "Python")
즉, *는 하나의 리스트나 튜플을 여러 개의 위치 인자로 풀어주는 역할을 합니다.
언패킹과 일반 전달의 차이
두 코드를 비교하면 차이를 쉽게 이해할 수 있습니다.
numbers = [10, 20, 30]
print(numbers)
이 경우 리스트 자체가 하나의 객체입니다.
반면 다음과 같이 작성하면:
print(*numbers)
리스트의 값이 각각 분리되어 전달됩니다.
결과:
10 20 30
함수에서도 같은 원리로 동작합니다.
def add(a, b, c):
return a + b + c
numbers = [10, 20, 30]
print(add(*numbers))
결과:
60
딕셔너리 언패킹
딕셔너리는 **를 사용해 언패킹할 수 있습니다.
다음과 같은 함수가 있다고 해보겠습니다.
def introduce(name, age, major):
print(name, age, major)
딕셔너리를 준비합니다.
student = {
"name": "철수",
"age": 20,
"major": "Python"
}
이 값을 함수에 전달할 때 **를 사용할 수 있습니다.
introduce(**student)
Python은 딕셔너리의 키를 매개변수 이름과 연결하고 값을 전달합니다.
결과:
철수 20 Python
즉,
introduce(**student)
는 다음과 비슷하게 동작합니다.
introduce(
name="철수",
age=20,
major="Python"
)
*와 **의 차이
파라미터 언패킹에서 가장 중요한 부분입니다.
| 문법 | 언패킹 대상 | 전달 방식 |
|---|---|---|
* | 리스트, 튜플 등 | 위치 인자 |
** | 딕셔너리 | 키워드 인자 |
예를 들어 다음과 같습니다.
numbers = [10, 20, 30]
add(*numbers)
*numbers는 리스트의 값을 위치에 따라 전달합니다.
반면:
student = {
"name": "철수",
"age": 20
}
introduce(**student)
**student는 딕셔너리의 키를 함수의 매개변수 이름으로 사용합니다.
언패킹할 때 매개변수와 이름이 맞아야 한다
딕셔너리 언패킹에서는 딕셔너리의 키와 함수의 매개변수 이름이 맞아야 합니다.
예를 들어 다음 함수가 있습니다.
def introduce(name, age):
print(name, age)
다음 딕셔너리는 정상적으로 사용할 수 있습니다.
student = {
"name": "철수",
"age": 20
}
introduce(**student)
하지만 키 이름이 다르면 문제가 발생합니다.
student = {
"student_name": "철수",
"student_age": 20
}
introduce(**student)
introduce()에는 student_name과 student_age라는 매개변수가 없기 때문에 오류가 발생합니다.
따라서 **를 사용할 때는 딕셔너리의 키와 함수 매개변수 이름의 관계를 확인해야 합니다.
언패킹은 여러 값의 전달을 간단하게 만들어준다
파라미터 언패킹은 데이터가 이미 리스트나 딕셔너리 형태로 존재할 때 특히 유용합니다.
예를 들어 사용자 정보를 딕셔너리로 관리하고 있다고 해보겠습니다.
user = {
"name": "철수",
"age": 20,
"major": "Python"
}
함수의 매개변수와 구조가 동일하다면 다음처럼 바로 전달할 수 있습니다.
def print_user(name, age, major):
print(f"{name} / {age} / {major}")
print_user(**user)
별도의 변수로 하나씩 꺼내서 전달하지 않아도 된다는 장점이 있습니다.
리스트의 일부만 언패킹할 수도 있다
언패킹은 함수 호출뿐만 아니라 Python에서 값을 분리할 때도 자주 사용됩니다.
예를 들어 다음과 같은 리스트가 있습니다.
numbers = [1, 2, 3, 4, 5]
앞의 값과 나머지를 나누고 싶다면 다음처럼 작성할 수 있습니다.
first, *rest = numbers
print(first)
print(rest)
결과:
1
[2, 3, 4, 5]
여기서 first에는 첫 번째 값이 들어가고 *rest에는 나머지 값들이 리스트 형태로 들어갑니다.
반대로 뒤쪽 값을 분리할 수도 있습니다.
*rest, last = numbers
print(rest)
print(last)
결과:
[1, 2, 3, 4]
5
이처럼 *는 함수 호출뿐 아니라 여러 값을 분리해서 받을 때도 활용됩니다.
함수 호출에서 언패킹할 때 주의할 점
언패킹하는 값의 개수와 함수의 매개변수 개수가 맞아야 합니다.
def add(a, b, c):
return a + b + c
numbers = [10, 20]
add(*numbers)
이 경우 a, b, c 세 개의 값이 필요한데 두 개만 전달되므로 오류가 발생합니다.
반대로 값이 너무 많아도 문제가 됩니다.
numbers = [10, 20, 30, 40]
add(*numbers)
따라서 *를 사용하기 전에 언패킹되는 값의 개수와 함수가 요구하는 매개변수를 확인하는 것이 좋습니다.
파라미터 패킹과 언패킹은 반대 개념이다
앞서 살펴본 언패킹은 하나로 묶여 있는 값을 여러 개로 풀어서 전달하는 것입니다.
반대로 여러 개의 값을 하나로 묶어서 받는 것을 파라미터 패킹(Parameter Packing)이라고 합니다.
예를 들어 다음과 같은 함수가 있습니다.
def add_all(*args):
return sum(args)
호출할 때 여러 값을 전달하면 함수 내부에서는 하나의 args로 묶여서 처리됩니다.
add_all(10, 20, 30)
여기서 *args는 여러 위치 인자를 하나의 튜플로 묶습니다.
이것이 파라미터 패킹입니다.
즉,
언패킹
하나로 묶인 값 → 여러 개의 인자
패킹
여러 개의 인자 → 하나로 묶인 값
패킹은 다음 글에서 별도로 자세히 살펴보겠습니다.
파라미터 언패킹 핵심 정리
이번 글에서 기억해야 할 핵심은 다음과 같습니다.
*를 사용하면 리스트나 튜플 등의 값을 여러 위치 인자로 풀어 전달할 수 있습니다.**를 사용하면 딕셔너리의 값을 키워드 인자로 풀어 전달할 수 있습니다.*언패킹에서는 값의 순서가 중요합니다.**언패킹에서는 딕셔너리의 키와 함수의 매개변수 이름이 중요합니다.- 함수가 요구하는 매개변수와 언패킹되는 값의 개수가 맞아야 합니다.
- 여러 값을 하나로 묶어 받는 것은 파라미터 패킹이라고 합니다.
마무리
파라미터 언패킹은 Python에서 리스트, 튜플, 딕셔너리에 들어 있는 데이터를 함수에 전달할 때 매우 유용한 기능입니다.
특히 다음 두 가지 형태를 먼저 기억해 두면 됩니다.
add(*numbers)
리스트나 튜플 등의 값을 위치 인자로 전달할 때 사용합니다.
introduce(**student)
딕셔너리의 값을 키워드 인자로 전달할 때 사용합니다.
언패킹에 익숙해지면 함수 호출뿐만 아니라 Python의 리스트 할당과 데이터 처리에서도 * 문법을 자연스럽게 활용할 수 있습니다.
다음 글에서는 언패킹과 반대되는 개념인 파라미터 패킹을 살펴보겠습니다.