Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 3132 – 확장된 이터러블 언패킹

Author:
Georg Brandl <georg at python.org>
Status:
Final
Type:
Standards Track
Created:
30-Apr-2007
Python-Version:
3.0
Post-History:


Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

이 PEP는 이터러블 언패킹 문법의 변경을 제안하며, “일반” 이름에 할당되지 않은 모든 항목의 리스트가 할당될 “모두 받는” 이름을 지정할 수 있도록 합니다.

예 하나가 천 마디 말보다 낫습니다:

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

근거

많은 알고리즘에서는 시퀀스를 “첫 번째 항목, 나머지” 쌍으로 분할해야 합니다. 새로운 문법을 사용하면,

first, rest = seq[0], seq[1:]

더 깔끔하고 아마도 더 효율적인 방식으로 대체됩니다:

first, *rest = seq

더 복잡한 언패킹 패턴에서는 새로운 문법이 훨씬 더 깔끔해 보이며, 번거로운 인덱스 처리가 더 이상 필요하지 않습니다.

또한 오른쪽 값이 리스트가 아니라 이터러블인 경우 슬라이싱하려면 먼저 리스트로 변환해야 합니다. 이 임시 리스트를 생성하지 않으려면 다음과 같은 방법을 사용해야 합니다

it = iter(seq)
first = it.next()
rest = list(it)

사양

단순 대입의 왼쪽에 있는 튜플(또는 리스트)에는 단일 별표가 앞에 붙은 표현식을 최대 하나 포함할 수 있습니다(확장 대입에는 언패킹이 정의되어 있지 않습니다). 이 표현식을 이후 “별표 표현식”이라고 하며, 리스트의 다른 표현식은 “필수” 표현식이라고 합니다. 이는 언패킹되는 이터러블에서 필수 표현식 중 어느 것에도 할당되지 않은 모든 항목의 리스트가 할당될 하위 표현식을 지정하며, 해당 항목이 없으면 빈 리스트가 할당됩니다.

예를 들어 seq가 슬라이스 가능한 시퀀스라면, seq에 요소가 두 개 이상 있는 경우 다음의 모든 대입은 서로 동등합니다:

a, b, c = seq[0], list(seq[1:-1]), seq[-1]
a, *b, c = seq
[a, *b, c] = seq

이터러블에 모든 필수 표현식에 할당할 만큼 충분한 항목이 없으면(현재와 마찬가지로) 오류입니다.

또한 다음과 같이 별표 표현식을 유일한 대입 대상으로 사용하는 것도 오류입니다

*a = range(5)

그러나 다음은 유효한 문법입니다:

*a, = range(5)

이 제안은 for 문과 같은 암시적 대입 컨텍스트의 튜플에도 적용된다는 점에 유의하십시오:

for a, *b in [(1, 2, 3), (4, 5, 6, 7)]:
    print(b)

다음을 출력합니다

[2, 3]
[5, 6, 7]

별표 표현식은 대입 대상일 때만 허용되며, 그 외의 곳에서 사용하는 것은(물론 함수 호출의 별표 인자는 제외하고) 오류입니다.

구현

문법 변경

이 기능을 사용하려면 새로운 문법 규칙이 필요합니다:

star_expr: ['*'] expr

이 두 규칙에서는 exprstar_expr으로 변경됩니다:

comparison: star_expr (comp_op star_expr)*
exprlist: star_expr (',' star_expr)* [',']

컴파일러 변경

별표 표현식을 나타내는 새로운 ASDL 표현식 유형 Starred가 추가됩니다. 여기서 도입된 별표 표현식 요소는 보편적이며, 이후 비대입 컨텍스트에서 yield *iterable 제안과 같은 다른 용도로 사용될 수도 있다는 점에 유의하십시오.

컴파일러는 별표 표현식이 유효하지 않은 모든 경우를 인식하고 이를 문법 오류로 표시하도록 변경됩니다.

새로운 바이트코드 명령어 UNPACK_EX가 추가되며, 그 인자는 하위 8비트에 별표 대상 앞의 필수 대상 개수를, 상위 8비트에 별표 대상 뒤의 필수 대상 개수를 가집니다. 별표 표현식이 없는 시퀀스를 언패킹할 때는 기존 UNPACK_ITERABLE 연산 코드를 유지합니다.

바이트코드 인터프리터 변경

ceval.c의 unpack_iterable() 함수가 argcntafter 매개변수를 통해 확장 언패킹을 처리하도록 변경되었습니다. UNPACK_EX의 경우 함수는 다음 작업을 수행합니다.

  • 별표가 붙은 항목 앞의 필수 대상에 해당하는 모든 항목을 수집합니다.
  • 이터러블에서 남은 모든 항목을 리스트로 수집합니다.
  • 리스트에서 별표가 붙은 항목 뒤의 필수 대상에 해당하는 항목을 꺼냅니다.
  • 단일 항목들과 크기가 조정된 리스트를 스택에 푸시합니다.

리스트나 튜플과 같이 알려진 타입의 이터러블을 언패킹하기 위한 지름길을 추가할 수 있습니다.

현재 구현은 SourceForge 패치 추적기 [SFPATCH]에서 찾을 수 있습니다. 이제 최소한의 테스트 케이스도 포함되어 있습니다.

승인

python-3000 목록 [1]에서 짧은 논의를 거친 후, Guido가 현재 형태로 PEP를 승인했습니다. 논의된 변경 가능 사항은 다음과 같습니다.

  • exprlist에서 마지막 항목으로 별표 표현식만 허용합니다. 이렇게 하면 언패킹 코드가 조금 단순해지고 별표 표현식에 이터레이터를 할당할 수 있습니다. 이 동작은 너무 예상 밖이기 때문에 거부되었습니다.
  • 별표 대상에 원본 이터러블과 동일한 타입을 제공하도록 시도합니다. 예를 들어 a, *b = 'hello'에서 b는 문자열 'ello'이 할당됩니다. 이는 좋아 보일 수 있지만, 모든 이터러블에 대해 일관되게 올바르게 처리하는 것은 불가능합니다.
  • 별표 대상을 리스트 대신 튜플로 만듭니다. 이는 함수의 *args와 일관되지만 결과를 추가로 처리하기는 더 어려워집니다.

참고 자료