파이썬 - 학습 내용 정리(1)

파이썬 학습

  • 파이썬의 함수는 무조건 식이다.
  • 식은 반환(return) 받는 것을 말한다. (a+b 도 식이다 -> None을 반환한다.)
  • lambda는 return 의미가 내재되어 있으므로, return을 사용하지 않는다.
    • ex) lambda a, b: return a + b (X) –> lambda a, b: a + b (O)
  • update()는 None을 return 한다.

stable sorting

  • 특정 기준에 따라 sort되지만 동일한 위치에서의 순서는 기존 정렬된 순서대로 sort되는 것
    • ex) [2, 7, 5, 6, 3, 4] –> 짝수가 먼저 오도록 sort –> [2, 6, 4, 7, 5, 3]

lazy evaluation

  • 계산의 결과값이 필요할 때까지만 계산을 늦추는 기법(지연 계산법, 최소 계산법)
  • map, filter, reduce 가 lazy evaluation에 속한다.
  • map()안에 iterable 객체가 들어가야 한다.
  • next(m)으로 계속 실행했을 때, 뒤에 인자가 더이상 없을 경우, StopIteration 오류 발생
  • map, filter –> generator 객체
    • 포함 관계 : generator < iterator < iterable
  • reduce : 자료구조를 연산을 통해 단 하나의 값으로 만드는 함수 (반환값은 list가 될 수도 있고, tuple이 될 수도 있다.)
    1
    2
    3
    4
    5
    6
    7
    8
    li = [2, 3, -5, 6, -2, 1, -10]

    result = reduce(lambda a, b: a+b, li)
    # (...((2+3)+(-5))+ ... + (-10)...)
    # return -5
    result = reduce(lambda a,b:a+b, li, 100)
    # (...((100+2)+3)+(-5))+...+(-10)...)
    # return 95
  • ex) 양수를 골라내어 제곱한 값을 리스트로 만들기
    1
    2
    3
    li = [2, 3, -5, 6, -2, 1, -10]
    result = list(map(lambda b : b ** 2, filter(lambda a : a > 0, li)))
    # result = [4, 9, 36, 1]

문자 수 계산

  • ex) 동일한 문자를 가진 list –> 문자를 key로, 동일한 문자 갯수를 value로 하는 dictionary
    1
    2
    3
    4
    5
    6
    from functools import reduce

    li = ['a', 'b', 'a', 'b', 'b', 'a', 'c', 'a']

    result = reduce(lambda dic, ch: dic.update({ch: dic.get(ch, 0)+1}) or dic, li, {})
    # result = {'a':4, 'b':3, 'c':1}

generator 함수

  • iterator를 생성해주는 function
    • iterator : next() 메소드를 이용하여 데이터에 순차적으로 접근 가능한 object
    • generator는 iterator의 부분집합이다.
  • 파이썬 coroutine function –> generator
    • corouting function : 함수 실행 도중, 실행 주도권을 다른 함수에 넘길 수 있고, 내가 원하는 시점에 다시 실행 주도권을 가져올 수 있는 함수
  • 파이썬 스택 프레임이 heap에 저장되어 있다.
  • yield를 만나면 주도권을 next(g)에 양도(yield)한다.

    • yield를 사용하여 순서대로 때에 맞게 호출해주는 함수
  • ex) generator를 사용하여 피보나치 수열 만들기

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    def fibo_gen(n):
    a = 0
    b = 1
    for _ in range(n):
    temp = a
    a = b
    b = temp + a
    yield temp
    # 방법2)
    # yield a
    # a, b = b, a+b
    return 'complete'

    # generator 객체 생성
    fibo = fibo_gen(10)

    # 첫번째 next() 호출하면, yield 만날때까지만 함수가 실행된다.
    # 뒤에 더이상 인자가 없는 경우, StopIteration 발생한다.
    try:
    for _ in range(11):
    print(next(fibo), end = ' ')
    except StopIteration as stop:
    print(stop.value)

    # 0 1 1 2 3 5 8 13 21 34 complete
  • ex) send() 예시

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    def gen():
    print('gen start')
    data1 = yield 1
    print(f'gen[1] : {data1}')
    data2 = yield 2

    print(f'gen[2] : {data2}')
    return 'done'

    g = gen()

    # 함수 실행 시작!
    # 실행 주도권을 gen()에 넘김
    first = g.send(None)
    # gen start
    # first = 1

    second = g.send('word')
    # gen[1] : world
    # second = 2

    try:
    g.send('hello')
    except StopIteration as exc:
    print(exc.value)
    # gen[2] : hello
    # done
  • ex) yield from

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    def gen():
    print('gen start')
    data1 = yield 1
    print(f'gen[1] : {data1}')
    data2 = yield 2
    print(f'gen[2] : {data2}')
    return 'done'

    # delegate : 위임
    # generator
    # yield from (gen 객체)
    def delegate():
    g = gen()
    print('start')
    # yield 모두 실행 후 return 값 받아서 ret로 할당
    ret = yield from g
    print('end')
    print(f'return value : {ret}')
    return ret

    g = delegate()

    first = g.send(None)
    # start
    # gen start

    second = g.send('world')
    # gen[1] : world

    g.send('hello')
    # gen[2] : hello
    # end
    # return value : done
    # -----------------------
    # StopIteration: done 발생
    1
    2
    3
    4
    # yield from 을 이용한 await 예시
    async def func():
    await asyncio.sleep()
    # await == yield from