Python에서 압축 풀기 연산자(*, **)를 사용하는 방법은 무엇입니까?

Python은 가장 많이 사용되는 프로그래밍 언어입니다. 오늘 여러분은 파이썬의 핵심이지만 종종 무시되는 기능 중 하나를 사용하는 방법을 배우게 될 것입니다.

다른 사람의 코드에서 * 및 **를 보거나 용도를 실제로 알지 못한 채 사용해 본 적이 있을 것입니다. 압축 풀기의 개념과 이를 사용하여 더 많은 파이썬 코드를 작성하는 방법을 살펴보겠습니다.

다음은 이 자습서를 읽는 동안 유용한 개념 목록입니다.

  • Iterable: 집합, 목록, 튜플 및 사전과 같이 for 루프에 의해 반복될 수 있는 모든 시퀀스
  • 호출 가능: 이중 괄호()를 사용하여 호출할 수 있는 Python 객체(예: myfunction())
  • Shell: Python 코드를 실행할 수 있는 대화형 런타임 환경입니다. 터미널에서 “python”을 실행하여 호출할 수 있습니다.
  • 변수: 객체를 저장하고 예약된 메모리 위치를 갖는 기호 이름.

가장 자주 혼동되는 것부터 시작해 보겠습니다. Python의 Asteristics는 산술 연산자이기도 합니다. 별표 하나

는 곱셈에 사용되며 그 중 두 개(**)는 지수를 나타냅니다.

>>> 3*3
9
>>> 3**3
27

Python 셸을 열고 다음을 입력하여 이를 증명할 수 있습니다.

참고: 이 튜토리얼을 따라하려면 Python 3가 설치되어 있어야 합니다. 아직 설치하지 않았다면 Python 설치 가이드를 확인하세요.

보시다시피 첫 번째 숫자 뒤와 두 번째 숫자 앞에 별표를 사용하고 있습니다. 이것을 보면 산술 연산자를 사용하고 있음을 의미합니다.

>>> *range(1, 6),
(1, 2, 3, 4, 5)
>>> {**{'vanilla':3, 'chocolate':2}, 'strawberry':2}
{'vanilla': 3, 'chocolate': 2, 'strawberry': 2}

반면에 우리는 iterable 앞에 별표(*, **)를 사용하여 압축을 풉니다. 예를 들면 다음과 같습니다.

이해하지 못하더라도 걱정하지 마십시오. 이것은 Python에서 압축을 풀기 위한 서문일 뿐입니다. 계속해서 전체 튜토리얼을 읽으십시오!

포장을 푸는 것은 무엇입니까?

언패킹은 목록, 튜플, 사전과 같은 이터러블을 꺼내는 과정입니다. 상자를 열고 케이블, 헤드폰 또는 USB와 같은 다양한 항목을 꺼내는 것으로 생각하십시오.

  카메라 및 기타 장치를 위한 21개의 TF 카드

파이썬에서 포장을 푸는 것은 실생활에서 상자를 푸는 것과 유사합니다.

>>> mybox = ['cables', 'headphones', 'USB']
>>> item1, item2, item3 = mybox

더 나은 이해를 위해 동일한 예제를 코드로 변환해 보겠습니다.

보시다시피 mybox 목록 내부의 세 항목을 세 변수 item1, item2, item2에 할당합니다. 이러한 종류의 변수 할당은 파이썬에서 언패킹의 기본 개념입니다.

>>> item1
'cables'
>>> item2
'headphones'
>>> item3
'USB'

각 항목의 값을 가져오려고 하면 item1은 “케이블”, item2는 “헤드폰” 등을 나타냅니다.

>>> newbox = ['cables', 'headphones', 'USB', 'mouse']
>>> item1, item2, item3 = newbox
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)

여기까지는 이 코드로 모든 것이 잘 된 것처럼 보이지만 더 많은 요소가 포함된 목록을 풀고 동일한 양의 할당된 변수를 유지하려면 어떻게 해야 할까요?

아마 이런 종류의 오류를 예상했을 것입니다. 본질적으로 우리는 4개의 목록 항목을 3개의 변수에 할당하고 있습니다. Python은 올바른 값을 할당하기 위해 어떻게 관리합니까? 그렇지 않습니다. 값 오류

“압축을 풀 값이 너무 많습니다”라는 메시지와 함께. 이는 왼쪽에 3개의 변수를 설정하고 오른쪽에 4개의 값(newbox 목록에 해당)을 설정하기 때문에 발생합니다.

>>> lastbox = ['cables', 'headphones']
>>> item1, item2, item3 = lastbox
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 2)

유사한 프로세스를 시도하지만 압축을 풀 값보다 더 많은 변수가 있는 경우 메시지가 약간 다른 것을 제외하고 또 다른 ValueError가 발생합니다.

참고: 우리는 목록으로 작업했지만 이터러블(목록, 집합, 튜플, 사전)과 함께 이 형식의 압축 해제를 사용할 수 있습니다.

그렇다면 이 상황을 어떻게 극복해야 할까요? 오류 없이 iterable의 모든 항목을 몇 가지 변수로 풀 수 있는 방법이 있습니까?

물론 있고, 언패킹 연산자 또는 별표 연산자(*, **)라고 합니다. 파이썬에서 어떻게 사용하는지 봅시다.

* 연산자를 사용하여 목록을 압축 해제하는 방법

별표 연산자

>>> first, *unused, last = [1, 2, 3, 5, 7]
>>> first
1
>>> last
7
>>> unused
[2, 3, 5]

아직 할당되지 않은 iterable의 모든 값을 압축 해제하는 데 사용됩니다.

>>> first, *_, last = [1, 2, 3, 5, 7]
>>> _
[2, 3, 5]

인덱스를 사용하지 않고 목록의 첫 번째 요소와 마지막 요소를 가져오고 싶다고 가정해 보겠습니다. 별표 연산자를 사용하면 됩니다.

>>> first, *_, last = [1, 2]
>>> first
1
>>> last
2
>>> _
[]

아시다시피 별표 연산자를 사용하여 사용하지 않은 모든 값을 가져옵니다. 값을 버리는 가장 좋은 방법은 밑줄 변수(_)를 사용하는 것입니다. 이 변수는 때때로 “더미 변수”로 사용됩니다.

  19 최고의 무료 디스코드 보이스 체인저

목록에 두 개의 요소만 있는 경우에도 이 트릭을 계속 사용할 수 있습니다.

이 경우 밑줄 변수(더미 변수)는 빈 목록을 저장하므로 주변의 다른 두 변수가 목록의 사용 가능한 값에 액세스할 수 있습니다.

>>> *string = 'PythonIsTheBest'

일반적인 문제 해결

>>> *string = 'PythonIsTheBest'
  File "<stdin>", line 1
SyntaxError: starred assignment target must be in a list or tuple

iterable의 고유한 요소를 풀 수 있습니다. 예를 들어, 다음과 같이 생각할 수 있습니다. 그러나 위의 코드는 SyntaxError를 반환합니다.이것은 에 따르면

PEP 사양

:

>>> *string, = 'PythonIsTheBest'
>>> string
['P', 'y', 't', 'h', 'o', 'n', 'I', 's', 'T', 'h', 'e', 'B', 'e', 's', 't']

간단한 할당의 왼쪽에 있는 튜플(또는 목록)

>>> *numbers, = range(5)
>>> numbers
[0, 1, 2, 3, 4]

iterable의 모든 값을 단일 변수로 풀고 싶다면 튜플을 설정해야 하므로 간단한 쉼표를 추가하는 것으로 충분합니다.

또 다른 예는 일련의 숫자를 반환하는 range 함수를 사용하는 것입니다.

별표로 목록과 튜플을 압축 해제하는 방법을 알았으니 이제 사전 압축을 해제할 차례입니다.

** 연산자로 사전의 압축을 푸는 방법

>>> **greetings, = {'hello': 'HELLO', 'bye':'BYE'} 
...
SyntaxError: invalid syntax

단일 별표는 목록과 튜플의 압축을 푸는 데 사용되지만 이중 별표(**)는 사전의 압축을 푸는 데 사용됩니다.

>>> food = {'fish':3, 'meat':5, 'pasta':9} 
>>> colors = {'red': 'intensity', 'yellow':'happiness'}
>>> merged_dict = {**food, **colors}
>>> merged_dict
{'fish': 3, 'meat': 5, 'pasta': 9, 'red': 'intensity', 'yellow': 'happiness'}

불행하게도 우리는 튜플과 리스트로 해왔던 것처럼 사전을 단일 변수로 압축해제할 수 없습니다. 즉, 다음은 오류를 발생시킵니다.

그러나 콜러블 및 기타 사전 내부에서 ** 연산자를 사용할 수 있습니다. 예를 들어 다른 사전에서 만든 병합된 사전을 만들려면 아래 코드를 사용할 수 있습니다.

이것은 복합 사전을 만드는 매우 짧은 방법이지만 Python에서 압축을 푸는 주요 접근 방식은 아닙니다.

콜러블과 함께 언패킹을 사용하는 방법을 살펴보겠습니다.

함수 패킹: args 및 kwargs

클래스나 함수에 구현되기 전에 args와 kwargs를 본 적이 있을 것입니다. 콜러블과 함께 사용해야 하는 이유를 살펴보겠습니다.

>>> def product(n1, n2):
...     return n1 * n2
... 
>>> numbers = [12, 1]
>>> product(*numbers)
12

* 연산자(args)로 패킹하기

>>> product(12, 1)
12

두 숫자의 곱을 계산하는 함수가 있다고 가정합니다.

>>> numbers = [12, 1, 3, 4]
>>> product(*numbers)
...
TypeError: product() takes 2 positional arguments but 4 were given

보시다시피 목록 번호를 함수로 풀고 있으므로 실제로 다음을 실행하고 있습니다.

>>> def product(*args):
...     result = 1
...     for i in args:
...             result *= i
...     return result
...
>>> product(*numbers)
144

여기까지는 모든 것이 잘 작동하지만 더 긴 목록을 전달하려면 어떻게 해야 할까요? 함수가 관리할 수 있는 것보다 더 많은 인수를 수신하기 때문에 확실히 오류가 발생합니다.

  2017년 Kickass Torrents에 대한 최고의 대안과 안전을 유지하는 방법

리스트를 함수에 직접 패킹함으로써 이 모든 것을 해결할 수 있습니다. 그러면 내부에 이터러블이 생성되고 함수에 얼마든지 인수를 전달할 수 있습니다.

여기에서 우리는 args 매개변수를 iterable로 취급하여 요소를 살펴보고 모든 숫자의 곱을 반환합니다. 0으로 시작하면 함수가 항상 0을 반환하기 때문에 결과의 시작 번호가 1이어야 한다는 점에 유의하십시오. 참고: args는 관례일 뿐이며 다른 매개변수 이름을 사용할 수 있습니다.내장 함수와 마찬가지로 목록을 사용하지 않고 함수에 임의의 숫자를 전달할 수도 있습니다.

>>> product(5, 5, 5)
125
>>> print(5, 5, 5)
5 5 5

인쇄 기능

>>> def test_type(*args):
...     print(type(args))
...     print(args)
... 
>>> test_type(1, 2, 4, 'a string')
<class 'tuple'>
(1, 2, 4, 'a string')

.

마지막으로 함수 인수의 개체 유형을 가져옵니다.

위의 코드에서 언급한 것처럼 args의 유형은 항상 튜플이며 그 내용은 함수에 전달된 키워드가 아닌 모든 인수입니다.

** 연산자로 패킹(kwargs)

>>> def make_person(name, **kwargs):
...     result = name + ': '
...     for key, value in kwargs.items():
...             result += f'{key} = {value}, '
...     return result
... 
>>> make_person('Melissa', id=12112, location='london', net_worth=12000)
'Melissa: id = 12112, location = london, net_worth = 12000, '

이전에 본 것처럼 ** 연산자는 사전에만 사용됩니다. 즉, 이 연산자를 사용하면 키-값 쌍을 매개변수로 함수에 전달할 수 있습니다.

위치 인수 “이름”과 정의되지 않은 양의 키워드 인수를 받는 make_person 함수를 만들어 봅시다.

보시다시피 **kwargs 문은 모든 키워드 인수를 함수 내에서 반복할 수 있는 사전으로 변환합니다.

>>> def test_kwargs(**kwargs):
...     print(type(kwargs))
...     print(kwargs)
... 
>>> test_kwargs(random=12, parameters=21)
<class 'dict'>
{'random': 12, 'parameters': 21}

참고: kwargs는 이 매개변수의 이름을 원하는 대로 지정할 수 있는 규칙일 뿐입니다.

args와 같은 방식으로 kwargs의 유형을 확인할 수 있습니다.

>>> def my_final_function(*args, **kwargs):
...     print('Type args: ', type(args))
...     print('args: ', args)
...     print('Type kwargs: ', type(kwargs))
...     print('kwargs: ', kwargs)
... 
>>> my_final_function('Python', 'The', 'Best', language="Python", users="A lot")
Type args:  <class 'tuple'>
args:  ('Python', 'The', 'Best')
Type kwargs:  <class 'dict'>
kwargs:  {'language': 'Python', 'users': 'A lot'}

kwargs 내부 변수는 항상 함수에 전달된 키-값 쌍을 저장하는 사전이 됩니다.

마지막으로 동일한 함수에서 args와 kwargs를 사용해 보겠습니다.

결론

  • 언패킹 연산자는 일상적인 작업에 정말 유용합니다. 이제 개별 명령문과 함수 매개변수 모두에서 연산자를 사용하는 방법을 알게 되었습니다.
  • 이 자습서에서는 다음을 배웠습니다.
  • 튜플과 목록에는 *를 사용하고 사전에는 **를 사용합니다.
  • 함수 및 클래스 생성자에서 압축 풀기 연산자를 사용할 수 있습니다.

인수는 키워드가 아닌 매개 변수를 함수에 전달하는 데 사용됩니다.kwargs는 키워드 매개변수를 함수에 전달하는 데 사용됩니다.