해당 글은
Yang Zhou
님의 5 Best Practices of Destructuring Assignments in Python 를 번역하였습니다.
변수에 value(값)
을 저장하는 방법은 프로그래밍의 기본 소양입니다.
어떤 프로그래밍 언어들 중에서도 특히나 파이썬의 경우 이러한 과정을 더욱 우아하게 처리할 수 있는 방법이 있죠.
예시를 한번 보도록 합시다.
a, *mid, b = [1, 2, 3, 4, 5, 6]
print(a, mid, b)
# 1 [2, 3, 4, 5] 6
위의 코드와 같이 *
을 통해 가운데의 mid
변수는 가운데 요소들(2,3,4,5)을 리스트로 받은 것을 확인할 수 있습니다.
이러한 방식이 파이썬에서의 구조분해 할당을 받는 방법 중 하나입니다.
해당 문서는 파이썬에서의 주요 구조분해할당 방법 가운데 가장 좋은 5가지 방법을 소개합니다.
이 글을 읽은 후 파이썬의 아름다움에 대해 느낄 수 있을 것입니다.
1. 요소를 적절하게 분해하고 할당하기
요소를 분해하는 기본적인/근본적인 방법은 간단합니다.
코드 한 줄로 Python의 iterable 한 요소를 여러 변수에 할당할 수 있습니다.
a,b,c = [1,2,3]
위의 방법은 전형적인 변수의 값 할당 사용법입니다.
이따금 우리는 이중(2차원)리스트를 할당해야할 때도 있을 겁니다.
이러한 경우 왼쪽과 오른쪽의 구조가 동일해야만 합니다. 그렇지 않으면 당연히 에러가 터지겠죠?
a,[b,c] = [1,[2,3]]
print(a,b,c)
# 1 2 3
2. _
를 통해 특정 요소의 구조할당 무시하기
연속적인 형태의 값을 가진 변수(Iterable한 값)의 모든 요소들이 사용될 필요는 없을 때도 있습니다.
이러한 경우 _(underscore)
가 유용하게 사용될 수 있죠.
a,_,c = [1,2,3]
print(a,c)
# 1 3
위의 코드를 통해
만약 우리가 두번째 요소인 2를 사용할 필요가 없다면 _
를 통해 해당 요소를 무시할 수 있을겁니다.
사실 이건 특별한 기법은 아닙니다. 그냥 _
라는 이름의 변수를 정의한 것 뿐입니다.
만약 _
를 프린트문을 통해 찍을 경우 당연히 2
가 찍힐 것입니다. 왜냐하면 이러한 꼼수(trick)는 그저 약속/협약(convention)이기 때문입니다.
이러한 _
가 아니더라도 어떠한 다른 이름의 변수로도 대체가 가능합니다.
하지만 _
를 사용하는 것이 변수 이름의 혼란을 주거나 모호함을 피할 수 있고 다른 파이썬 개발자들이 이해하기가 쉽기 때문입니다.
3. *
를 사용하여 여러 요소들을 하나의 변수에 리스트로 집합시키기
글의 첫부분에서 언급했다시피 만약 우리가 특정 부분들의 연속된 값들만 하나의 리스트로 넣고 싶다면
밑의 한 줄의 코드가 가장 유용할 것입니다.
a,*mid, b = [1,2,3,4,5,6]
print(a,mid,b)
# 1 [2,3,4,5] 6
이때 가운데 연속된 요소들을 모두 무시하고 싶다면?
- 그냥
*
과_
만을 함께 사용하면 됩니다.
a,*_,b = [1,2,3,4,5,6]
print(a,b)
# 1 6
4. For 루프문에 구조분해할당 적용하기
구조분해할당 방법은 for문을 상요할 때도 유용하고 쉽게 쓰입니다.
예를 들어, 아래의 코드와 같이 Object자료형을 연속적으로 뽑아낼 때 다음과 같이 사용할 수 있습니다.
genius = {
'name': "Yang",
'sex': "Male",
'job': "Programmer"
}
for k, v in genius.items():
print(k, v)
# name Yang
# sex Male
# job Programmer
Object형태의 자료형이 지나치게 복잡해질 경우, for문을 다음과 같이 수정합니다.
genius = {
'name': ["Yang", "others"],
'sex': ["Male", " "],
'job': ["Programmer", "others"]
}
for k, (v1, v2) in genius.items():
print(k, v1, v2)
# name Yang others
# sex Male
# job Programmer others
그러므로 코드 안에서 for문을 사용하는 부분이 너무 지저분하거나 마음에 들지 않을 경우
다음과 같은 구조분해 할당 방식을 고려해보는 것도 좋습니다.
5. Dictionary자료형의 구조분해 할당
파이썬에서 Dictionary 자료형의 구조분해할당 방법은 조금 복잡할 수 있습니다.
genius = {
'name': "Yang",
'sex': "Male",
'job': "Programmer"
}
n, s, j = genius
print(n, s, j)
# name sex job
위의 코드에서 보시다시피
왼쪽의 변수들(n,s,j)은 genius 객체의 key값만 할당받는 것을 볼 수 있습니다.
만약 genius객체의 값(value)을 할당받고 싶다면 다음과 같이 하면 됩니다.
genius = {
'name': "Yang",
'sex': "Male",
'job': "Programmer"
}
n, s, j = genius.values()
print(n, s, j)
# Yang Male Programmer
하지만 위의 방법을 자세히 들여다보면 숨겨진 버그가 존재합니다.
바로
genius.values()
의 순서가 보장되지 않는다는 것입니다.
다시 말하자면 n
변수에는 name
이, s
변수에는 sex
, j
변수에는 job
의 순서
로 할당되는 것을 보장하지 않습니다!
이러한 문제를 해결하는 방법은 OrderedDict
를 사용하는 것입니다.
OrderedDict란, 파이썬의 Dictionary자료형의 변형으로써 순서를 보장하는 자료형입니다.
하지만 고작 이것 하나 때문에 원본 dictionary 변수를 바꾸고싶진 않을 것입니다..
귀찮아하실 필요도 걱정하실 필요도 없습니다. 파이썬은 분명 더 좋은 해결법을 가지고 있으니까요.
from operator import itemgetter
genius = {
'name': "Yang",
'sex': "Male",
'job': "Programmer"
}
j, n, s = itemgetter('job', 'name', 'sex')(genius)
print(j, n, s)
# Programmer Yang Male
위에서 보시다시피 operator
모듈의 itemgetter
함수가 이러한 귀찮음의 좋은 해결책이 되어줄 겁니다.
이 메소드에 우리가 원하는 할당 순서대로 key의 이름을 전달하면 됩니다.
그러면 우리가 전달한 key의 순서를 지켜서 value값이 할당된 것을 확인할 수 있습니다.
결론
구조분해할당 방법은 파이썬에서 아주 훌륭한 문법이며 유용합니다.
이러한 방법들을 잘 활용한다면 우리 코드는 보다 우아한 코드가 되겠지요.
The destructuring assignments techniques are sweet syntax sugar in Python. If we use them well, our code will become much more elegant.
참고
https://medium.com/techtofreedom/four-usage-scenarios-of-underscores-in-python-e61de6a1003
https://medium.com/techtofreedom/5-uses-of-asterisks-in-python-3007911c198f
지나친 의역이나 오역에 대한 지적을 환영합니다.
'파이썬 문법' 카테고리의 다른 글
파이썬 상대경로 사용 시 주의 (0) | 2023.04.05 |
---|---|
파이썬에서 input() 대신 사용할 것 (0) | 2023.03.03 |
Hash Table (0) | 2022.10.09 |
파이썬 타입 지정하기 (0) | 2022.07.30 |
언어의 성능에 일희일비 하지 말기 (0) | 2022.07.24 |