unpacking & enumerate & zip & assignment expression

About_work·2023년 1월 8일
0

python 기초

목록 보기
3/65

boolean X -> if/else O

  • 복잡한 식 대신, 도우미 함수를 최대한 활용해라.
  • 코드를 줄여 쓰는 것보다, 가독성을 좋게 하는 것이 더 가치 있다.
  • boolean 연산자 “or 나 and” 를 식에 사용하는 것보다, if /else를 사용하는 것이 낫다.
Red = my_values.get(‘빨강’, [‘ ’])[0] or 0 # 이런 or 구문보다, if/else를 명시적으로 써라.

unpacking

  • unpacking
    • 한 문장 안에서 여러 값을 대입할 수 있는 문법
    • 모든 iterable에 적용할 수 있음
    • iterable이 여러 계층으로 내포된 경우에도 unpacking을 적용할 수 있다.
    • index를 사용해 sequence 내부에 접근하는 대신, unpacking을 사용해 코드를 더 명확하게 만들라.
    • 파이썬은 list 구조, 함수 argument, keyword argument, 다중 return 값 등에 대한 unpacking 기능도 제공한다.

unpacking 예시 1

  • 임시 변수를 정의하지 않고도 값을 맞바꾸려면, unpacking을 사용하라.
def bubble_sort(a):
    for _ in range(len(a)):
        for i in range(1, len(a)):
            if a[i] < a[i-1]:
                a[i-1], a[i] = a[i], a[i-1] # 맞바꾸기


names = ['프레즐', '당근', '쑥갓', '베이컨']
bubble_sort(names)
print(names)

unpacking 예시 2

  • for 루프 또는 그와 비슷한 다른 요소(comprehension 이나 generator 식) 의 대상인 list의 원소를 unpacking 하자.
  • indexing을 이용하는 대신에.
  • 목적: 코드를 더 짧고, 이해하기 쉽게 쓰기 위함
Snacks = [(`베이컨‘, 350), (’도넛‘, 240), (’머핀‘, 190)]
For rank, (name, calories) in enumerate(snacks, 1):
    Print(f’#{rank}: {name} 은 {calories} 칼로리 입니다.‘)

range 보다는 enumerate 를 사용하라.

  • range: 어떤 정수 집합을 iteration 하는 루프가 필요할 때 유용
  • enumerate
    • 루프를 돌면서, iteator에서 가져오는 원소의 인덱스까지 얻을 수 있다.
    • iterator을 lazy generator로 감싼다.
    • loop index와 iterator 의 다음 값으로 이뤄진 쌍을 넘겨준다. (Yield)
    • 두 번째 파라미터로, 어디부터 수를 세기 시작할지를 지정할 수 있다.
For i, flavor in enumerate(flavor_list, 1):
    Print(f{i}: {flavor})

8: 여러 iterator에 대해 나란히 loop를 실행하려면 zip을 사용

names = ['Cecilia', '남궁민수', '毛泽东']
counts = [len(n) for n in names]

for name, count in zip(names, counts):
    if count > max_count:
        longest_name = name
        max_count = count
  • zip은 둘 이상의 iterator을 지연 계산 generator 을 사용해 묶어준다.
  • zip generator은 각 iterator의 다음 값이 들어 있는 tuple을 반환한다.
import itertools
for name, count in itertools.zip_longest(names, counts):
    print(f'{name}: {count}')
  • zip은 자신이 감싼 iterator 중 어느 하나가 끝날 때까지만 tuple을 내놓는다. (가장 짧은 iterator에 맞춰 길이가 제한된다.)
  • 길이가 서로 다른 iterator에 대해, 긴 쪽에 맞추어 loop를 수행하려면 itertools 내장 모듈의 zip_longest 함수를 이용하라.

9: for이나 while 루프 뒤에 else 블록을 사용하지 말라.

  • 동작이 직관적이지 않고 혼동을 야기할 수 있으므로, 루프 뒤에 else 블록을 하지말라.

10: 대입식을 사용해 반복을 피하라.

if (count := fresh_fruit.get('바나나', 0)) >= 2:
    pieces = slice_bananas(count)
    to_enjoy = make_smoothies(pieces)
elif (count := fresh_fruit.get('사과', 0)) >= 4:
    to_enjoy = make_cider(count)
elif count := fresh_fruit.get('레몬', 0):
    to_enjoy = make_lemonade(count)
else:
    to_enjoy = '아무것도 없음'
  • 대입식

    • assignment expression
    • walrus operator
    • a := b
    • a walrus b 라고 읽음
    • python 3.8 부터 지원
  • 일반 대입문

    • assignment statement
    • a = b
    • a equal b 라고 읽음
  • 대입식 왜써?

    • 대입문이 쓰일 수 없는 위치에서, 변수에 값을 대입할 수 있으므로 유용하다.

    • 하나의 식 안에서, 변수 이름에 값을 대입하면서 이 값을 평가할 수 있고, 중복을 피할 수 있다.

    • 위 예시에서 대입 연산자는

      • 우선 count에 변수의 값을 대입하고,
      • if 문의 맥락에서 대입된 값을 평가
  • 예시 2

bottles = []
while fresh_fruit := pick_fruit():
    for fruit, count in fresh_fruit.items():
        batch = make_juice(fruit, count)
        bottles.extend(batch)

print(bottles)
profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글