Batter way13

매일 공부(ML)·2022년 2월 7일
0

파이썬 코딩의 기술

목록 보기
12/27

슬라이싱보다는 나머지를 모두 잡아내는 언패킹을 사용하라

  • 기본 언패킹의 유일한 단점은 바로 시퀀스의 길이를 미리 정해야합니다.(그렇지 않으면 에러 발생)
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인스턴스

    • 시퀀스에 남는 원소가 없을 경우 별표 식 부분은 빈 리스트

      • 원소가 최소 N개 들어있다는 사실을 미리 아는 시퀀스 처리 용이(코테용이)

고려할 점

별표 식은 항상 리스트를 만들기에 이터레이터로 사용하면 컴퓨터 메모리를 다 사용해서 멈추게 되는 현상이 벌어지기에 겨로가 데이터가 모두 메모리에 들어갈 수 있을 때만 사용하는 것을 추천합니다.


*별표 식 예시

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개 또는 그 이상 들어갑니다.

  • 리스트를 서로 겹치지 않게 여러 조각으로 나눌 경우, 슬라이싱과 인덱싱을 사용하기 보다는 나머지를 모두 잡아내는 언패킹을 사용하면 실수가 줄어들 것입니다.

profile
성장을 도울 아카이빙 블로그

0개의 댓글