728x90
반응형

파이썬 asterisk(*) 이란

파이썬에서 asterisk(*) 은 다음과 같은 상황에서 사용된다.

  1. 곱셈 및 거듭제곱 연산으로 사용할 때
  2. 리스트형 컨테이너 타입의 데이터를 반복 확장하고자 할 때
  3. 가변인자(Variadic Arguments) 를 사용하고자할 때
  4. 컨테이너 타입의 데이터를 Unpacking 할 때

 

 

곱셈 및 거듭제곱 연산으로 사용할 때

곱셈 연산 (*)
>>> 2 * 3
6

 

거듭제곱 연산 (**)
>>> 2 ** 3
8

 

 

리스트형 컨테이너 타입의 데이터를 반복 확장하고자 할 때

리스트 생성 및 확장
# '0'의 값을 가진 길이가 100인 리스트 생성
lst = [0] * 100

 

튜플 생성 및 확장
# '0' 의 값을 가진 길이가 100인 튜플 생성
tp = (0,) * 100

 

 

가변인자(Variadic Arguments) 를 사용하고자할 때

어떤 함수에서 가변 인자를 필요로할 때가 있다.

예를 들어, 들어오는 인자의 갯수를 모르거나 어떤 인자라도 모두 받아서 처리해야하는 때가 있다.

파이썬에서 인자의 종류는 2가지가 있는데 하나는 Positional Arguments 이고 다른 하나는 Keyword Arguments 이다.

 

Positional Arguments위치에 따라 정해지는 인자라고 할 수 있고

Keyword Arguments키워드를 가지는 인자, 이름을 가지는 인자라고 할 수 있다.

def ranking(first, second, third=None, fourth=None):
    rank = {}
    rank[1], rank[2] = first, second
    rank[3] = third if third is not None else 'Nobody'
    rank[3] = fourth if fourth is not None else 'Nobody'
    print(rank)
  • 함수 실행 결과
>>> ranking('jeong', 'hyeon')
{1: 'jeong', 2: 'hyeon', 3: 'Nobody'}

>>> ranking('jeong', 'hyeon', third="min")
{1: 'jeong', 2: 'hyeon', 3: 'Nobody'}

>>> ranking('jeong', 'hyeon', "min", fourth='park')
{1: 'jeong', 2: 'hyeon', 3: 'park'}

 

위와 같은 함수가 있다고 했을 때 인자의 구분은 다음과 같이 할 수 있다.

Positional Arguments 는 first, second , Keyword Arguments 는 third=None, fourth=None

 

Positional Arguments 는 생략이 불가능하고 갯수대로 정해진 위치에 인자를 전달해야 한다.

Keyword Arguments 는 함수 선언 시 기본 값으로 설정할 수 있고 생략을 하더라도 기본값이 인자의 값으로 들어간다. 즉, 생략이 가능하다. 

따라서 Keyword Arguments 생략이 가능하기 때문에 Positional Arguments 이전에 선언될 수 없다.

그래서 아래의 코드는 에러가 발생한다.

def ranking(first, second=None, third, fourth=None):
# 에러 코드
Cell In[14], line 1
    def ranking(first, second=None, third, fourth=None):
                                    ^
SyntaxError: non-default argument follows default argument

만약 10명의 사람의 랭킹을 정해야 하는데 위와 같이 인자를 하나씩 다 설정해줄 수 는 없다.

이때 사용하는게 바로 가변 인자(Variadic Arguments) 이다.

위에서 설명한 Keyword ArgumentsPositional Arguments 를 모두 사용할 수 있고 다음과 같이 사용할 수 있다.

 

 

Positional Arguments 를 가변인자로 받는 경우

*agrs 는 임의의 갯수의 Positional Arguments 를 받겠다는 의미이다.

  • 함수 생성
def ranking(*args):
    print(args)
  • 함수 실행 결과
>>> ranking('jeong', 'hyeon', "min", 'park')
('jeong', 'hyeon', 'min', 'park')

 

 

Keyword Arguments 를 가변인자로 받는 경우

**kwargs 는 임의의 갯수의 Keyword Arguments 를 받겠다는 의미이다.

  • 함수 생성
def ranking(**kwargs):
    print(kwargs)
  • 함수 실행 결과
>>> ranking(fst = 'jeong', scd = 'hyeon', trd = "min", frd = 'park')
{'fst': 'jeong', 'scd': 'hyeon', 'trd': 'min', 'frd': 'park'}

이때, *args, **kwargs 형태로 가변인자를 받는 것을 packing 이라고 한다.

*args 의 형태로 전달되는 인자들은 agrs 라는 tuple 에 저장되고

**kwargs 의 형태로 전달되는 인자들은 kwargs 라는 dict 에 저장된다.

 

아까 말했듯이 Positional 과 Keyword 는 순서에 유의해야 한다.

따라서 Positional 보다 Keyword 가 앞에 오게 되면 에러가 발생한다.

# 에러 발생
def ranking(**kwargs, *args):

 

 

컨테이너 타입의 데이터를 Unpacking 할 때

Asterisk(*) 는 컨테이너 타입의 데이터를 unpacking 하는 경우에도 사용할 수 있다.

가변 인자를 사용하는 경우와 마찬가지로 종종 사용하는 기능이다.

 

예를 들어 list, tuple, dict 의 타입을 가지는 가변인자를 함수에서 받는 경우 사용할 수 있다.

즉, 인자 값으로 list, tuple, dict 타입이 들어가는 경우를 말한다.

from functools import reduce # 연산의 결과를 누적하는 함수

primes = [2, 3, 5, 7, 11, 13]

def prod(*num):
    p = reduce(lambda x, y : x * y, num)
    return p

primes 라는 리스트가 있고 이때 함수에 넣어준다고 해보자.

함수에서는 인자를 Positional Arguments 로 받는다.

>>> prod(primes)
[2, 3, 5, 7, 11, 13]

실행 결과를 보는 것과 같이 리스트 하나를 인자로 받아서 그대로 출력하는 것을 확인할 수 있다.

따라서, 리스트를 unpacking 해서 전달해야 하는 것을 알 수 있다.

 

unpacking 은 리스트 앞에 * 을 붙여주면 리스트이 원소들이 unpacking 되어 num 이라는 리스트에 저장된다.

쉽게 말해서 primes 의 원소들을 하나씩 꺼내와서 num 이라는 리스트에 저장해준다.

>>> prod(*primes)
30030

 

추가로 dict 의 경우에는 * 대신 ** 으로 unpacking 을 해줘야 한다.

예를 들어, dict 는 아래와 같이 사용된다.

headers = {
    'Accept': 'text/plain',
    'Content-Length': 348,
    'Host': 'https://jaynamm.tistory.com'
}

def pre_process(**headers):
    content_length = headers['Content-Length']
    print('content length: ', content_length)

    host = headers['Host']
    if 'https' not in host:
        raise ValueError('You must use SSL for http communication')
  • 함수 실행 결과
>>> pre_process(**headers)
content length:  348

 

dictunpacking 을 하게 되면 다음과 같이 key 값이 나오는 것을 확인할 수 있다.

headers = {
    'Accept': 'text/plain',
    'Content-Length': 348,
    'Host': 'https://jaynamm.tistory.com'
}

>>> print(*headers)
Accept Content-Length Host

 

 

추가적으로 unpacking 에 대해서 예를 들어 사용해봤다.

numbers = [1, 2, 3, 4, 5]
>>> *a, = numbers
>>> print(a)
[1, 2, 3, 4, 5]
>>> *a, b = numbers
>>> print(a, b)
[1, 2, 3, 4] 5
>>> a, *b = numbers
>>> print(a, b)
1 [2, 3, 4, 5]
>>> a, *b, c = numbers
>>> print(a, b, c)
1 [2, 3, 4] 5

 

 

참고 사이트

파이썬의 Asterisk(*) 이해하기

728x90
반응형
복사했습니다!