car_ages = [0,9,4,8,7,20,19,1,6,15]
car_ages_descending = sorted(car_ages, reverse=True)
oldset, second_oldest = car_ages_descending
#Traceback...
#ValueError: too many values to unpack
*슬라이싱
원하는 결과는 나올지라도 시각적 잡음이 심하다
지금은 집합이 적지만 여러 집합이 생기면 인덱스 오류가 생깁니다.
oldest = car_ages_descending[0]
second_oldest = car_ages_descending[1]
others = car_ages_descending[2:]
print(oldest, second_oldest, others)
# 20,19,[15,9,8,7,6,4,1,0]
*해결책
별표 식(starred expression)사용하여 모든 값을 담는 언패킹 지원
언패킹 패턴에서 못 들어가는 모든 값을 별이 붙은 부분에선 다 담기 가능
코드의 가독성 증가 및 인덱스 경계로 인한 오류X
별표 식을 다양한 위치에서 사용이 가능하다
별표 식이 포함된 언패킹 대입을 처리하려면 필수인 부분이 적어도 하나있어야 한다. 그렇지 않으면 SyntaxError발생
즉, 별표 식만 사용해서 언패킹 불가
한 수준의 언패킹 패턴을 두 개 이상 사용 불가
여러 계층의 구조인 언패킹 패턴에서 서로 다른 부분에서 별표 사용이 가능하므로 이때는 두 개 이상 사용 가능
별표식은 항상 list인스턴스
시퀀스에 남는 원소가 없을 경우 별표 식 부분은 빈 리스트
고려할 점
별표 식은 항상 리스트를 만들기에 이터레이터로 사용하면 컴퓨터 메모리를 다 사용해서 멈추게 되는 현상이 벌어지기에 겨로가 데이터가 모두 메모리에 들어갈 수 있을 때만 사용하는 것을 추천합니다.
*별표 식 예시
oldest, second_oldest, *others = car_ages_descending
print(oldest, second_oldest, others)
# 20 19 [15,9,8,7,6,4,1,0]
*다른 위치도 가능
oldest, *other, youngest = car_ages_descending
print(oldest, youngest, others) # 20 0 [19,15,9,8,7,6,4,1]
*others, second_youngest, youngest = car_ages_descending
print(youngest, second_youngest, others) # 0 1 [20,19,15,9,8,7,6,4]
*별표 식만 사용하여 언패킹 불가
*others = car_ages_descending
#Traceback...
#SyntaxError: starred assignment target must be in a list or tuple
*한 수준의 언패킹에서 별표 식 두 개 사용 불가
first, *middle, *second_middle, last = [1,2,3,4]
#Traceback...
#SyntaxError: two starred expressions in assignment
*여러 계층에선 별표 식 두 개 이상 사용 가능
car_inventory = {
'시내': ('그랜저', '아반떼', '티코')
'공항': ('제네시스 쿠페', '소나타', 'K5', '엑센트'),
}
((loc1, (best1, *rest1)),
(loc2, (best2, *rest2))) = car_inventory.items()
print(f'{loc1} 최고는 {best1}, 나머지는 {len(rest1)} 종') #시내 최고는 그랜저, 나머지 2 종
print(f'{loc2} 최고는 {best2}, 나머지는 {len(rest2)} 종') #공항 최고는 제네시스 쿠페, 나머지 3종
*별표 식은 항상 list인스턴스
short_list = [1,2]
first, second, *rest = short_list
print(first, second, rest) # 1 2 []
*별표 식을 추가하면 언패킹할 이터레이터의 값을 깔끔하게 가져올 수 있다
#쓰기 전
def generate_csv():
yield ('날짜', '제조사', '모델', '연식', '가격')
all_csv_rows = list(generate_csv())
header = all_csv_rows[0]
rows = all_csv_rows[1:]
print('CSV 헤더:', header) #CSV 헤더: ('날짜', '제조사', '모델', '연식', '가격')
print('행 수:', len(rows)) #행 수: 200
#쓴 후
def generate_csv():
yield ('날짜', '제조사', '모델', '연식', '가격')
it = generate_csv()
header, *rows = it
print('CSV 헤더:', header) #CSV 헤더: ('날짜', '제조사', '모델', '연식', '가격')
print('행 수:', len(rows)) #행 수: 200
언패킹 대입에 별표 식을 사용한다면, 대입이 안되는 모든 부분을 리스트로 잡을 수 있다.
별표 식은 언패킹 패턴의 어떤 위치에서 놓일 수 있기에 별표 식에 대입된 결과는 항상 리스트가되고, 이 리스트에는 별표 식이 받은 값이 0개 또는 그 이상 들어갑니다.
리스트를 서로 겹치지 않게 여러 조각으로 나눌 경우, 슬라이싱과 인덱싱을 사용하기 보다는 나머지를 모두 잡아내는 언패킹을 사용하면 실수가 줄어들 것입니다.