Python 13 패킹 & 언패킹,위치인자 & 키워드인자

김민호·2021년 9월 27일
0

Python

목록 보기
14/16

1. 대입문과 시퀀스

1) 패킹(packing)

  • 원래 변수 하나에는 데이터 하나만을 대입할 수 있고, 변수 하나가 여러 개의 데이터를 가리키도록 하기 위해선 데이터들을 컬렉션에 담고 변수에 대입해야 함
  • 여러 개의 데이터를 컬렉션으로 묶어 변수에 대입하는 것을 패킹
  • numbers = (1, 2, 3, 4, 5)

2) 언패킹(unpacking)

  • 컬렉션 속의 요소들을 여러 개의 변수에 나누어 대입
numbers = [1, 2, 3, 4, 5]

이 시퀀스를 하나씩 변수에 담아야 할 때

a = numbers[0]
b = numbers[1]
c = numbers[2]
d = numbers[3]
e = numbers[4]

print(a, b, c, d, e)
# 1 2 3 4 5

상당히 번거롭지 아니할 수가 없다. 이를 간단하게 하기 위해서

(a, b, c, d, e) = numbers
# (a, b, c, d, e) = [1, 2, 3, 4, 5]

이렇게 좌변과 우변이 둘 다 시퀀스이면, 우변의 각 요소가 좌변이 각 요소에 순서대로 대입된다.
이렇게 컬렉션의 요소를 여러 개의 변수에 나누어 담는 방법이 언패킹(unpacking)

  • 컬렉션을 튜플로 작성할 때는 괄호 생략 가능. 대입문에서 패킹과 언패킹을 수행할 때 괄호를 생략하는 경우가 많음
numbers = 1, 2, 3, 4, 5  # 패킹
a, b, c, d, e = numbers  # 언패킹

언패킹할 때, 즉 시퀀스의 요소를 변수 시퀀스에 나눠 대입할 때는 두 시퀀스의 길이가 일치해야 함

a, b, c = 1, 2, 3, 4, 5
print(a, b, c)
# ValueError: too many values to unpack (expected 3)
# 이렇게 대입문 양 변의 시퀀스 길이가 다르면 오류가 발생함

대입하고 싶지 않은 요소는 관례적으로 _ 변수로 설정해주면 됨

a, b, _, d, _ = [5, 6, 7, 8, 9]
print(a, b, d)
# 5, 6, 8

* 기호로 남은 요소를 대입받을 변수 지정

a = numbers[0]            # a = 1
b = numbers[1]            # b = 2
rest = numbers[2:]        # rest = (3, 4, 5)
print(a, b, rest)
# 1 2 (3, 4, 5)

a, b, *rest = numbers     # 1, 2를 제외한 나머지를 rest에 대입
print(a, b, rest)
# 1 2 [3, 4, 5]

*rest, c, d, e = numbers  # 3, 4, 5를 제외한 나머지를 rest에 대입
print(rest)
# [1, 2]

a, *rest, e = numbers     # 1, 5를 제외한 나머지를 rest에 대입
print(rest)
# [2, 3, 4]

2. 함수의 매개변수와 시퀀스 패킹, 언패킹

1) 시퀀스를 언패킹하여 매개변수에 전달

def date(y, m, d):
  return str(y) + '년' + str(m) + '월' + str(d) + '일'
  
today = (2021, 9, 27)

print(date(today))
# TypeError: date() missing 2 required positional arguments: 'm' and 'd'

이렇게 생각없이 하면 될 것 같지만 안 됨! 매개변수는 3개인데 인수로 1개만 받았기 때문!
날짜를 제대로 출력하기 위해서는 보통 이렇게 시퀀스에서 하나씩 꺼내서 전달

print(date(today[0], today[1], today[2]))
# 2021년9월27일

하지만 살짝 귀찮다. 이럴 때 언패킹 사용
여기서 today가 가변인자

print(date(*today)
# 2021년9월27일

print(date(*(2021, 9, 27)))
# 2021년9월27일

이렇게 시퀀스가 담긴 변수에도 사용 가능하고 변수에 대입하지 않은 시퀀스에도 사용 가능

print(date(2021, *(9, 27)))
# 2021년9월27일

이렇게 일부 매개변수에 다른 값을 전달한 뒤 남은 매개변수에 부분적으로 적용도 가능

2) 여러 개의 데이터를 시퀀스로 묶어서 하나의 매개변수에 전달

def mean(*args):
  return sum(args) / len(args)


print(mean(1))
print(mean(1,2,3,4,5,6,7,8,9,10))
print(mean(5,6,7))

몇 개의 인자를 받아도 상관없이 모든 데이터를 시퀀스 하나로 묶어서 하나의 매개변수에 전달할 때, 함수에서 이를 전달받기 위해서는 어쨌든 매개변수가 정의되어 있어야 함. 시퀀스 패킹 매개변수로 사용할 변수의 이름은 자유롭게 지어도 되지만 보통 인자들(arguments)을 의미하는 args가 주로 사용되고 이름 앞에 * 기호를 붙이면 됨

numbers = 1, 2, 3, 4, 5
print(mean(*numbers))

mena() 함수에 numbers 튜플의 요소를 모두 전달하고 싶을 때 시퀀스 언패킹을 활용하면 간편!
시퀀스 패킹과 언패킹을 활용하면 함수가 여러 개의 데이터를 유연하게 전달받도록 할 수 있다

3. 키워드 인자와 딕셔너리 언패킹

  • 키워드 인자 : 매개변수에 이름으로 일치시키는 인자
    함수를 호출할 때 인자의 값 뿐만 아니라 그 이름까지 명시적으로 지정해서 전달하는 방식.
  • 위치 인자 : 순서대로 값이 parameter로 전달

func(keyword="value")

def person_info(name, age, address):
  print('이름 :', name)
  print('나이 :', age)
  print('주소 :', address)


person_info(name="김민호", age=30, address='경기도 안양시')
# 이름 : 김민호
# 나이 : 30
# 주소 : 경기도 안양시
  • 위치인자는 항상 키워드 인자보다 앞에 와야 한다
person_info("지광선", 30, address='경기도 안양시') # 가능
person_info(name="최은환", 30, '경기도 안양시') 
# 불가능 
# syntaxError: positional argument follows keyword argument

func(**dictionary)

def person_info(name, age, address):
  print('이름 :', name)
  print('나이 :', age)
  print('주소 :', address)


x = { 'name':'김태훈', 'age':30, 'address' : '경기도 안양시'}

person_info(**x)
# 이름 : 김태훈
# 나이 : 30
# 주소 : 경기도 안양시

**x처럼 딕셔너리를 언패킹하면 딕셔너리의 key들이 함수의 인자로 들어감

키워드 가변인자(**kwargs)

키워드 가변인자 만들기

def personal_info(**kwargs):
  for kw, arg in kwargs.items():
    print(kw, ': ', arg, sep='')

a = {'name':'김민호', 'age':30}
personal_info(**a)

b = {'햄버거':'맥도날드', '피자':'도미노피자', '치킨':'교촌치킨'}
personal_info(**b)

고정인자 + 가변인자
고정 위치 인자
가변 위치 인자
고정 키워드 인자
가변 키워드 인자

https://python.bakyeono.net/chapter-5-5.html
https://sikaleo.tistory.com/113

profile
개발자로서의 삶은 https://velog.io/@maxminos 에서 기록하고 있습니다 😀

0개의 댓글