복붙노트

[PYTHON] 다른 반복 가능한 것을 N 개의 그룹으로 그룹화하는 Python 생성기 [duplicate]

PYTHON

다른 반복 가능한 것을 N 개의 그룹으로 그룹화하는 Python 생성기 [duplicate]

나는 iterable i와 size n을 취하고 길이 n의 튜플을 생성한다.이 튜플은 i에서 순차 값이다.

x = [1,2,3,4,5,6,7,8,9,0]
[z for z in TheFunc(x,3)]

주는

[(1,2,3),(4,5,6),(7,8,9),(0)]

그런 기능이 표준 라이브러리에 존재합니까?

표준 라이브러리의 일부로 존재하는 경우 찾을 수 없는데 검색 조건이 부족합니다. 나는 내 자신의 글을 쓸 수는 있지만, 나는하지 않을 것이다.

해결법

  1. ==============================

    1.itertools 패키지에 대한 문서에서 그루퍼 제조법을 참조하십시오.

    itertools 패키지에 대한 문서에서 그루퍼 제조법을 참조하십시오.

    def grouper(n, iterable, fillvalue=None):
      "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
      args = [iter(iterable)] * n
      return izip_longest(fillvalue=fillvalue, *args)
    

    (그러나 이것은 몇 가지 질문이 중복 된 것입니다.)

  2. ==============================

    2.최종 그룹에 채우기 값을 채우지 않고 반복자를 n 개의 청크로 그룹화하려면 iter (lambda : list (IT.islice (iterable, n)), [])를 사용하십시오.

    최종 그룹에 채우기 값을 채우지 않고 반복자를 n 개의 청크로 그룹화하려면 iter (lambda : list (IT.islice (iterable, n)), [])를 사용하십시오.

    import itertools as IT
    
    def grouper(n, iterable):
        """
        >>> list(grouper(3, 'ABCDEFG'))
        [['A', 'B', 'C'], ['D', 'E', 'F'], ['G']]
        """
        iterable = iter(iterable)
        return iter(lambda: list(IT.islice(iterable, n)), [])
    
    seq = [1,2,3,4,5,6,7]
    print(list(grouper(3, seq)))
    

    산출량

    [[1, 2, 3], [4, 5, 6], [7]]
    

    이 대답의 후반부에 어떻게 작동하는지에 대한 설명이 있습니다.

    반복자를 n 개의 청크로 그룹화하고 마지막 그룹을 채우기 값으로 채우려면 그룹화 래서 피 zip_longest (* [iterator] * n)를 사용하십시오.

    예를 들어, Python2에서 :

    >>> list(IT.izip_longest(*[iter(seq)]*3, fillvalue='x'))
    [(1, 2, 3), (4, 5, 6), (7, 'x', 'x')]
    

    Python3에서, izip_longest는 이제 zip_longest로 이름이 변경되었습니다 :

    >>> list(IT.zip_longest(*[iter(seq)]*3, fillvalue='x'))
    [(1, 2, 3), (4, 5, 6), (7, 'x', 'x')]
    

    n 개의 청크로 시퀀스를 그룹화하려면 청크 레시피를 사용할 수 있습니다.

    def chunks(seq, n):
        # https://stackoverflow.com/a/312464/190597 (Ned Batchelder)
        """ Yield successive n-sized chunks from seq."""
        for i in xrange(0, len(seq), n):
            yield seq[i:i + n]
    

    일반적으로 반복자와 달리 시퀀스의 길이는 정의되어 있습니다 (즉, __len__이 정의 됨).

  3. ==============================

    3.이건 어때? 그래도 채우기 값이 없습니다.

    이건 어때? 그래도 채우기 값이 없습니다.

    >>> def partition(itr, n):
    ...     i = iter(itr)
    ...     res = None
    ...     while True:
    ...             res = list(itertools.islice(i, 0, n))
    ...             if res == []:
    ...                     break
    ...             yield res
    ...
    >>> list(partition([1, 2, 3, 4, 5, 6, 7, 8, 9], 3))
    [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    >>>
    

    원본 iterable의 사본을 사용하며, 각 연속 splice에 대해 소모됩니다. 나의 피곤한 두뇌가 도달 할 수있는 다른 방법은 범위로 스플 라이스 엔드 포인트를 생성하는 것이 었습니다.

    아마도 나는 list ()를 tuple ()로 바꿔야 출력에 더 잘 대응할 수있다.

  4. ==============================

    4.이것은 Python에서 매우 일반적인 요청입니다. 보론 통합 유틸리티 패키지에 들어간 것으로 충분합니다. 우선 여기에는 광범위한 문서가 있습니다. 또한이 모듈은 표준 라이브러리 (Python 2 및 3 호환)에만 의존하도록 설계되고 테스트되었습니다. 즉, 파일을 프로젝트에 직접 다운로드 할 수 있습니다.

    이것은 Python에서 매우 일반적인 요청입니다. 보론 통합 유틸리티 패키지에 들어간 것으로 충분합니다. 우선 여기에는 광범위한 문서가 있습니다. 또한이 모듈은 표준 라이브러리 (Python 2 및 3 호환)에만 의존하도록 설계되고 테스트되었습니다. 즉, 파일을 프로젝트에 직접 다운로드 할 수 있습니다.

    # if you downloaded/embedded, try:
    # from iterutils import chunked
    
    # with `pip install boltons` use:
    
    from boltons.iterutils import chunked 
    
    print(chunked(range(10), 3))
    # [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
    

    무한 / 긴 시퀀스에 대해서도 반복자 / 생성자 형식이 있습니다.

    print(list(chunked_iter(range(10), 3, fill=None)))
    # [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, None, None]]
    

    보시다시피 원하는 값으로 시퀀스를 채울 수도 있습니다. 마지막으로, 관리자로서 수천 명의 개발자가 코드를 다운로드 / 테스트했지만 문제가 발생하면 GitHub Issues 페이지에서 가장 빠른 지원을받을 수 있습니다. 희망이 (그리고 / 또는 다른 150 + boltons 요리법 중 하나) 도움이!

  5. ==============================

    5.more_itertools 패키지에서 chunked 함수를 사용합니다.

    more_itertools 패키지에서 chunked 함수를 사용합니다.

    $ pip install more_itertools
    $ python
    >>> x = [1,2,3,4,5,6,7,8,9,0]
    >>> [tuple(z) for z in more_itertools.more.chunked(x, 3)]
    [(1, 2, 3), (4, 5, 6), (7, 8, 9), (0,)]
    
  6. ==============================

    6.이것은 매우 오래된 질문이지만 일반적인 경우에 대해 다음 접근법을 언급하는 것이 유용하다고 생각합니다. 주요 이점은 데이터를 한 번만 반복하면되므로 데이터베이스 커서 나 다른 시퀀스를 한 번만 사용할 수 있다는 것입니다. 나는 또한 그것을 더 읽기 쉽다고 생각한다.

    이것은 매우 오래된 질문이지만 일반적인 경우에 대해 다음 접근법을 언급하는 것이 유용하다고 생각합니다. 주요 이점은 데이터를 한 번만 반복하면되므로 데이터베이스 커서 나 다른 시퀀스를 한 번만 사용할 수 있다는 것입니다. 나는 또한 그것을 더 읽기 쉽다고 생각한다.

    def chunks(n, iterator):
        out = []
        for elem in iterator:
            out.append(elem)
            if len(out) == n:
                yield out
                out = []
        yield out
    
  7. ==============================

    7.이 답변을 여러 번했지만 나는 둘 다, 시퀀스 및 반복기, 가독성 (StopIteration 예외에 의해 보이지 않는 루프 종료 조건) 및 성능을 그룹화 제조법에 비해 둘 다 개선해야 내 솔루션을 추가 할거야. 그것은 Svein의 마지막 답과 가장 유사합니다.

    이 답변을 여러 번했지만 나는 둘 다, 시퀀스 및 반복기, 가독성 (StopIteration 예외에 의해 보이지 않는 루프 종료 조건) 및 성능을 그룹화 제조법에 비해 둘 다 개선해야 내 솔루션을 추가 할거야. 그것은 Svein의 마지막 답과 가장 유사합니다.

    def chunkify(iterable, n):
        iterable = iter(iterable)
        n_rest = n - 1
    
        for item in iterable:
            rest = itertools.islice(iterable, n_rest)
            yield itertools.chain((item,), rest)
    
  8. ==============================

    8.여기에 itertools를 사용하지 않는 다른 솔루션이 있습니다. 몇 줄이 더 있지만 iterable 길이보다 훨씬 짧은 청크가있을 때 주어진 답보다 성능이 월등히 좋습니다. 그러나 큰 덩어리의 경우 다른 답변은 훨씬 빠릅니다.

    여기에 itertools를 사용하지 않는 다른 솔루션이 있습니다. 몇 줄이 더 있지만 iterable 길이보다 훨씬 짧은 청크가있을 때 주어진 답보다 성능이 월등히 좋습니다. 그러나 큰 덩어리의 경우 다른 답변은 훨씬 빠릅니다.

    def batchiter(iterable, batch_size):
        """
        >>> list(batchiter('ABCDEFG', 3))
        [['A', 'B', 'C'], ['D', 'E', 'F'], ['G']]
        """
        next_batch = []
        for element in iterable:
            next_batch.append(element)
            if len(next_batch) == batch_size:
                batch, next_batch = next_batch, []
                yield batch
        if next_batch:
            yield next_batch
    
    
    In [19]: %timeit [b for b in batchiter(range(1000), 3)]
    1000 loops, best of 3: 644 µs per loop
    
    In [20]: %timeit [b for b in grouper(3, range(1000))]
    1000 loops, best of 3: 897 µs per loop
    
    In [21]: %timeit [b for b in partition(range(1000), 3)]
    1000 loops, best of 3: 890 µs per loop
    
    In [22]: %timeit [b for b in batchiter(range(1000), 333)]
    1000 loops, best of 3: 540 µs per loop
    
    In [23]: %timeit [b for b in grouper(333, range(1000))]
    10000 loops, best of 3: 81.7 µs per loop
    
    In [24]: %timeit [b for b in partition(range(1000), 333)]
    10000 loops, best of 3: 80.1 µs per loop
    
  9. ==============================

    9.

        def grouper(iterable, n):
            while True:
                yield itertools.chain((next(iterable),), itertools.islice(iterable, n-1))
    
  10. from https://stackoverflow.com/questions/3992735/python-generator-that-groups-another-iterable-into-groups-of-n by cc-by-sa and MIT license