[Effective Python] Lists and Dictionaries

u8cnk1·2023년 1월 5일
0

Chapter 2: Lists and Dictionaries

List ⇒ 반복 작업을 수행하는데에 적합
Dictionary ⇒ key와 그에 대응하는 value를 가짐, 할당 및 액세스에 대해 일정한 시간 성능을 제공하므로 동적 정보를 기록하는 데 이상적

Item 11: Slicing

slicing 구문 기본 형식 : list[start:end]

  • start 포함(0으로 시작하는 경우 생략)
  • end는 제외
  • a[:]는 모든 요소를 선택
  • 음수를 인덱스로 사용할 수 있다.
  • 범위를 벗어난 인덱스를 적절하게 처리한다.
  • slicing의 결과는 새로운 list → slicing의 결과를 수정해도 원래 리스트에 영향을 주지 X

Item 12: Stride

slice의 stride 구문 : list[start:end:stride]

  • stride를 사용하여 list의 짝수 또는 홀수 인덱스로 쉽게 그룹화할 수 있다.
  • stride를 -1로 slicing하면 문자열을 반전시킨다.
  • 그러나 slice에서 start, end, stride를 모두 지정하면 혼란스러울 수 있다.(예: x[-2:2:-2])
    -> 시작 또는 끝 인덱스가 없는 slice에서 양의 stride 값 사용하기
    -> 음의 stride 피하기
    -> 세 가지 매개변수가 모두 필요한 경우, 두번에 걸쳐 할당하거나(하나는 stride하고 다른 하나는 slicing 수행) itertools의 islice 사용하기

Item 13: Catch-All Unpacking

  1. slicing 사용
car_ages = [0, 9, 4, 8, 7, 20, 19, 1, 6, 15]
car_ages_descending = sorted(car_ages, reverse=True) # 내림차순 정렬

oldest = car_ages_descending[0]
second_oldest = car_ages_descending[1]
others = car_ages_descending[2:]
print(oldest, second_oldest, others)
  1. catch-all unpacking 사용
oldest, second_oldest, *others = car_ages_descending
print(oldest, second_oldest, others)
  • list를 겹치지 않는 조각으로 나눌 때 catch-all unpacking을 사용
  • *로 표시된 표현식을 사용하여 다른 부분에 할당되지 않은 모든 값을 목록으로 가져올 수 있다.
  • 모든 위치에 * 표현식을 사용할 수 있으며, 항상 0 이상의 값을 포함한다.
  • slicing 보다 코드가 짧고 읽기 쉬우며 오류 발생률이 낮다.

Item 14: Key parameter를 이용한 정렬

  • list, string, tuple 등 -> 다양한 기준에 따라 항목을 정렬하는 방법 제공(default: 오름차순)

  • 정렬에 사용할 객체에 속성이 있는 경우 -> key parameter 사용

    • key function : 정렬 중인 항목의 단일 인수 전달
    • lambda 키워드 사용하여 정렬 기준 지정하여 key parameter function 정의
    • key parameter로 전달된 lambda 함수 내에서 item attribute에 접근하거나 item(sequences, tuples, dictionaries)으로 인덱싱, 또는 다른 valid expression을 사용할 수 있다.
      tools = [
      	Tool('level', 3.5),
      	Tool('hammer', 1.25),
      	Tool('screwdriver', 0.5),
      	Tool('chisel', 0.25),
      ]
      tools.sort(key=lambda x: x.name) 		```   
  • 여러 기준을 사용하여 정렬하는 경우 -> tuple type 사용

    • 숫자 값을 정렬하는 경우 -연산자를 사용하여 정렬 방향을 혼합할 수 있다.
    • 예: power_tools.sort(key=lambda x: (-x.weight, x.name))
    • 또는 동일한 list에서 여러 번 정렬을 호출하여 서로 다른 기준을 결합할 수 있다.

Item 15: dict Insertion Ordering

  • 파이썬 3.5 이전 버전 -> dict를 반복할 때 key가 임의의 순서로 반환
    (파이썬 인터프리터가 시작될 때 할당된 hash 내장 함수와 랜덤 시드의 조합으로 hash table 알고리즘을 구현했기 때문에 item이 삽입된 순서와 일치하지 X)
    , popitem 실행시 랜덤으로 항목 선택
  • 파이썬 3.6 버전 이후 -> 일관된 삽입 순서 제공
    • dict 인스턴스의 내용이 처음에 key가 추가된 순서와 동일한 순서로 반복된다.
    • popitem 실행시 마지막에 삽입된 항목을 선택
    • **kwargs 등의 키워드 인수를 프로그래머가 원래 함수를 호출한 방법과 일치하도록 유지함
    • class에서 instance 필드의 할당 순서가 dict에 반영됨
    • dicionary-like class를 다룰때 :
      1. 삽입 순서에 의존하지 않는 코드 작성
      2. 런타임에 명시적으로 dict 유형 확인
      3. type annotation 및 static analysis를 사용하여 dict 인스턴스가 되도록 강제하기

Item 16: Handle Missing Dictionary Keys

  • dictionary와 상호작용하는 작업: key 및 관련 값에 액세스, 할당, 삭제

  • dict type -> 존재하는 key를 가져오거나 기본값을 반환하는 작업을 수행하기 위해 get 메소드 제공

    • counter와 같은 기본 유형을 포함하는 dictionary에 가장 적합
# 누릭된 key 값 다루기

counters = {
	'pumpernickel': 2,
	'sourdough': 1,
}

# 방법1) if문 사용 - key가 존재하면 True 반환
key = 'wheat'
	if key in counters:
		count = counters[key]
	else:
 		count = 0

counters[key] = count + 1

# 방법2) KeyError exception
try:
	count = counters[key]
except KeyError:
	count = 0
    
counters[key] = count + 1

# 방법3) get method 이용
count = counters.get(key, 0)	# 두 번째 parameter는 첫 번째 parameter key가 없는 경우 반환할 기본값을 의미
counters[key] = count + 1
  • 또한 dict type은 setdefault method를 제공한다.

    • setdefault : dictionary에서 key값을 가져오려고 시도
      key가 없으면 제공된 기본값에 해당 key를 할당한다.
      count = counters.setdefault(key,0)
      그 후 해당 key의 값(현재 값 또는 새로 삽입된 기본값)을 반환한다.

Item 17: Handle Missing Items - defaultdict

  • built-in module collectionsdefaultdict는 key가 없을 때 default value를 자동으로 저장한다.
    (from collections import defaultdict)
  • 임의의 잠재적 key 집합을 관리하기 위해 dictionary를 만드는 경우 적합
  • 여분의 집합 인스턴스가 할당되지 않으며, 추가 method가 많은 횟수로 호출될 경우 setdefault보다 defaultdict를 사용하는 것이 좋다.

Item 18: Know How to Construct Key-Depedent Default Values with missing

  • setdefault method는 default값을 생성할 때 예외가 발생할 수 있는 경우 적합하지 X

  • defaultdict로 전달된 함수는 default 값을 액세스하는 key에 의존할 수 X

  • __missing__ method 사용

    • dict type을 하위 분류하고 특수 method를 구한하여 누락된 key를 처리하기 위한 방법을 추가할 수 있다.
    • dictionary에 key가 없는 것을 발견하면 __missing__ method 호출 -> key에 대한 새 default 값을 만들어 dictionary에 삽입하여 호출자에게 반환

0개의 댓글