파이썬 이해 및 생성기 표현식

이 장은 이해와 생성기 표현식을 어떻게 사용하여 비추고 여과하며 간략하게 조작하는지 보여줄 것이다.교체기와 yield 문장도 이해할 수 있습니다.

이해력
앞에서 말한 바와 같이 파이톤은 map()filter() 내장 함수를 제공했다.이해는 더욱 간결하고 빠른 실현 방식을 제공했다.그러나 문법은 이해하고 익히는 데 시간이 걸릴 수도 있다.
이해의 최저 요구는 매핑 표현식 (함수 호출 포함) 과 순환입니다.다음 예는 다음과 같습니다.
>>> nums = (321, 1, 1, 0, 5.3, 2)

# manual implementation
>>> sqr_nums = []
>>> for n in nums:
...     sqr_nums.append(n * n)
... 
>>> sqr_nums
[103041, 1, 1, 0, 28.09, 4]

# list comprehension
>>> [n * n for n in nums]
[103041, 1, 1, 0, 28.09, 4]
상술한 list 이해의 일반적인 형식은 [expr loop]이다.수동 실현과 비교하면 append()는 자동적으로 실행되고 이것은 대부분의 성능 장점의 원천이다.list 이해는 list 출력 정의를 바탕으로 하고 for 순환하는 입력은 모든iterable(예를 들어 상례의tuple일 수 있음을 주의하십시오.
다음은 필터 작업의 예이다.다음 사항이 아닙니다.
# manual implementation
def remove_dunder(obj):
    names = []
    for n in dir(obj):
        if '__' not in n:
            names.append(n)
    return names

# using 'filter' function
def remove_dunder(obj):
    return list(filter(lambda n: '__' not in n, dir(obj)))
다음과 같은 구문을 사용할 수 있습니다.
>>> def remove_dunder(obj):
...     return [n for n in dir(obj) if '__' not in n]
... 
>>> remove_dunder(dict)
['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop',
 'popitem', 'setdefault', 'update', 'values']
상술한 이해의 일반적인 형식은 [expr loop condition]이다.만약 네가 수동으로 실현할 수 있다면, 쉽게 판본을 이해할 수 있을 것이다.먼저 표현식append() 방법에 전달되는 매개 변수)을 배치하고 수동과 같은 순서에 따라 배치 순환과 조건을 배치한다.연습을 통해 너는 자연스럽게 판본을 읽고 쓸 수 있을 것이다.
다음은 zip() 함수의 예입니다.
>>> p = [1, 3, 5]
>>> q = [3, 214, 53]
>>> [i + j for i, j in zip(p, q)]
[4, 217, 58]
>>> [i * j for i, j in zip(p, q)]
[3, 642, 265]
다음은 네스트된 주기의 예입니다.
>>> names = ['Jo', 'Joe', 'Jon']
>>> pairs = []
>>> for i, n1 in enumerate(names):
...     for n2 in names[i+1:]:
...         pairs.append((n1, n2))
... 
>>> pairs
[('Jo', 'Joe'), ('Jo', 'Jon'), ('Joe', 'Jon')]
# note that the loop order is same as the manual implementation
>>> [(n1, n2) for i, n1 in enumerate(names) for n2 in names[i+1:]]
[('Jo', 'Joe'), ('Jo', 'Jon'), ('Joe', 'Jon')]
이와 유사하게, 당신은 dict 문자가 아닌 set 문자를 사용하여 {} 구축하고 [] 이해할 수 있습니다.() 문자의 이해 문법이 생성기 표현식으로 바뀌었기 때문에 tuple() 이해가 필요하다.tuple, list()dict()를 각각 사용하여 set()[]를 대체할 수 있습니다.
>>> marks = dict(Rahul=68, Ravi=92, Rohit=75, Rajan=85, Ram=80)
>>> {k: v for k, v in marks.items() if v >= 80}
{'Ravi': 92, 'Rajan': 85, 'Ram': 80}

>>> colors = {'teal', 'blue', 'green', 'yellow', 'red', 'orange'}
>>> {c for c in colors if 'o' in c}
{'yellow', 'orange'}

>>> dishes = ('Poha', 'Aloo tikki', 'Baati', 'Khichdi', 'Makki roti')
>>> tuple(d for d in dishes if len(d) < 6)
('Poha', 'Baati')
여전히 구문 이해에 대해 곤혹스러워하는 경우 다음을 참조하십시오.
  • List comprehensions explained visually
  • Comprehensions in Python the Jedi way
  • calmcode.io: video on comprehensions

  • 교체기
    쿼트 섹션docs.python glossary: iterator:

    An object representing a stream of data. Repeated calls to the iterator’s __next__() method (or passing it to the built-in function next()) return successive items in the stream. When no more data are available a StopIteration exception is raised instead.


    이전 절의 {} 예는 filter() 함수에 전달하여 list() 대상의 출력을 얻는 등 진일보한 처리를 필요로 한다.list 함수가 되돌아오는 대상의 행동이 교체기와 유사하기 때문이다.iterables를 사용할 수 있는 어느 곳에서든 교체기를 전달할 수 있습니다. 예를 들어 filter() 순환.다음 예는 다음과 같습니다.
    >>> filter_obj = filter(lambda n: '__' not in n, dir(tuple))
    >>> filter_obj
    <filter object at 0x7fd910e2de80>
    >>> for x in filter_obj:
    ...     print(x)
    ... 
    count
    index
    
    iterable와 교체기 사이의 차이점은 iterable에서 임의의 횟수를 교체할 수 있다는 것이다. (만약 내가 이렇게 말할 수 있다면, 이것은 그야말로 빙빙 돌려서 하는 말이다.)또한 for 함수는 교체기에 사용할 수 있지만iterables에 사용할 수 없습니다.일단 교체기를 다 소모하면 다른 항목(예를 들어 next()이나 next() 순환)을 얻으려는 시도는 for 이상을 초래할 수 있다.교체기는 lazy and memory efficient 용기에 넣지 않고 필요할 때만 결과를 계산하기 때문이다.
    >>> names = filter(lambda n: '__' not in n, dir(tuple))
    >>> next(names)
    'count'
    >>> next(names)
    'index'
    >>> next(names)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    
    iter() 내장 함수를 사용하여iterable를 교체기로 변환할 수 있습니다.
    >>> nums = [321, 1, 1, 0, 5.3, 2]
    >>> iter(nums)
    <list_iterator object at 0x7fd90e7f8ee0>
    
    다음은 aStopIteration에서 무작위 항목을 반복적으로 가져오지 않는 실용적인 예입니다.
    >>> import random 
    >>> names = ['Jo', 'Ravi', 'Joe', 'Raj', 'Jon']
    >>> random.shuffle(names)
    >>> random_name = iter(names)
    >>> next(random_name)
    'Jon'
    >>> next(random_name)
    'Ravi'
    

    생산량list 문장 대신 yield를 사용하여 교체기를 만드는 함수를 생성기라고 합니다.참조:

    Each time next() is called on it, the generator resumes where it left off (it remembers all the data values and which statement was last executed).


    이것은 피보나치 발생기이다.
    >>> def fibonacci(n):
    ...     a, b = 0, 1
    ...     for _ in range(n):
    ...         yield a
    ...         a, b = b, a + b
    ... 
    >>> fibonacci(5)
    <generator object fibonacci at 0x7fd90e7b22e0>
    >>> list(fibonacci(10))
    [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
    
    자세한 토론 및 기능에 대한 자세한 내용은 다음을 참조하십시오.
  • docs.python: Generators
  • stackoverflow: What does the yield keyword do?
  • Yield and Generators Explained
  • docs.python: itertools
    생성기 표현식
    문자return의 이해 문법은 생성기 표현식이라고 하는 교체기를 만든다.언제든지 iterable를 한 번 사용해야 한다면, 생성기 표현식을 사용하는 것이 이해하는 것보다 훨씬 효율적이고 빠르다."이해"를 사용하면 값을 용기에 저장하면 메모리를 낭비할 수 있으며, 다음 예시의 () 함수를 통해 이 값을 처리한 후에만 버려집니다.
    >>> nums = [100, 53, 32, 0, 11, 5, 2]
    >>> (n * n for n in nums)
    <generator object <genexpr> at 0x7fd90e7b22e0>
    >>> g = (n * n for n in nums)
    >>> next(g)
    10000
    
    # here's a generator version of the sum_sqr_evens(iterable) function
    # note that () is optional here for the generator expression
    >>> sum(n * n for n in nums if n % 2 == 0)
    11028
    
    # inner product
    >>> sum(i * j for i, j in zip((1, 3, 5), (2, 4, 6)))
    44
    
    다음은 사용 방법sum()의 예입니다.
    >>> items = (1, 'hi', [10, 20], 'bye')
    >>> ':'.join(items)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: sequence item 0: expected str instance, int found
    >>> ':'.join(str(i) for i in items)
    '1:hi:[10, 20]:bye'
    

    연습하다

  • 값을 오름차순으로 정렬한 사전을 되돌려 주는 함수를 만듭니다.
    >>> marks = dict(Rahul=86, Ravi=92, Rohit=75, Rajan=79, Ram=92)
    >>> sort_by_value(marks)
    {'Rohit': 75, 'Rajan': 79, 'Rahul': 86, 'Ravi': 92, 'Ram': 92}
    

  • 다음 규칙에 따라 문자열 세그먼트join()를 반환하는 함수를 작성합니다.
  • 입력 문자열의 길이가 3자
  • 보다 작으면 고유한 요소로 반환
  • 그렇지 않으면 2자 이상의 문자가 포함된 모든 세그먼트를 반환합니다.
  • >>> word_slices('i')
    ['i']
    >>> word_slices('to')
    ['to']
    >>> word_slices('table')
    ['ta', 'tab', 'tabl', 'table', 'ab', 'abl', 'able', 'bl', 'ble', 'le']
    
  • 제곱 짝수와 입방 홀수.예를 들어 list는 당신에게 [321, 1, -4, 0, 5, 2]를 출력으로 주어야 합니다.
  • 제곱값이 [33076161, 1, 16, 0, 125, 4]보다 작을 때만 숫자의 제곱을 계산한다.50의 출력은 (7.1, 1, -4, 8, 5.1, 12)이어야 한다.
  • 좋은 웹페이지 즐겨찾기