[python] 리스트를 대략 같은 길이의 N 개 부분으로 나누기

목록을 대략 동일한 부분 으로 나누는 가장 좋은 방법은 무엇입니까 ? 예를 들어,리스트에 7 개의 요소가 있고이를 2 개의 파트로 나누면 한 파트에 3 개의 요소를 가져오고 다른 하나에는 4 개의 요소가 있어야합니다.

내가 좋아하는 뭔가를 찾고 있어요 even_split(L, n)그 휴식 Ln부품.

def chunks(L, n):
    """ Yield successive n-sized chunks from L.
    """
    for i in range(0, len(L), n):
        yield L[i:i+n]

위의 코드는 3 청크가 아닌 3 청크를 제공합니다. 나는 단순히 전치 (이 항목을 반복하고 각 열의 첫 번째 요소를 가져 와서 그 부분을 호출 한 다음 두 번째 부분을 넣고 두 번째 부분에 넣는 등) 할 수는 있지만 항목의 순서를 파괴합니다.



답변

반올림 오류로 인해이 코드가 손상되었습니다. 사용하지 마십시오 !!!

assert len(chunkIt([1,2,3], 10)) == 10  # fails

다음은 작동 할 수있는 것입니다.

def chunkIt(seq, num):
    avg = len(seq) / float(num)
    out = []
    last = 0.0

    while last < len(seq):
        out.append(seq[int(last):int(last + avg)])
        last += avg

    return out

테스트 :

>>> chunkIt(range(10), 3)
[[0, 1, 2], [3, 4, 5], [6, 7, 8, 9]]
>>> chunkIt(range(11), 3)
[[0, 1, 2], [3, 4, 5, 6], [7, 8, 9, 10]]
>>> chunkIt(range(12), 3)
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]


답변

간단히 목록 생성기로 쓸 수 있습니다.

def split(a, n):
    k, m = divmod(len(a), n)
    return (a[i * k + min(i, m):(i + 1) * k + min(i + 1, m)] for i in range(n))

예:

>>> list(split(range(11), 3))
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10]]


답변

이것은 * 의 raison d’ être 입니다 numpy.array_split:

>>> import numpy as np
>>> print(*np.array_split(range(10), 3))
[0 1 2 3] [4 5 6] [7 8 9]
>>> print(*np.array_split(range(10), 4))
[0 1 2] [3 4 5] [6 7] [8 9]
>>> print(*np.array_split(range(10), 5))
[0 1] [2 3] [4 5] [6 7] [8 9]

* 6 호실에서 제로 피레 우스 에게 신용


답변

연속 덩어리와 같은 바보 같은 것을 원하지 않는 한 :

>>> def chunkify(lst,n):
...     return [lst[i::n] for i in xrange(n)]
...
>>> chunkify(range(13), 3)
[[0, 3, 6, 9, 12], [1, 4, 7, 10], [2, 5, 8, 11]]


답변

n청크 대신 청크 를 생성하도록 코드 변경 n:

def chunks(l, n):
    """ Yield n successive chunks from l.
    """
    newn = int(len(l) / n)
    for i in xrange(0, n-1):
        yield l[i*newn:i*newn+newn]
    yield l[n*newn-newn:]

l = range(56)
three_chunks = chunks (l, 3)
print three_chunks.next()
print three_chunks.next()
print three_chunks.next()

이것은 다음을 제공합니다.

[0, 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]
[36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55]

이것은 최종 그룹에 여분의 요소를 할당하지만 완벽하지는 않지만 “대략 N 동등한 부분”에 대한 귀하의 사양에 부합합니다. (18,18,20).

다음 코드를 사용하여보다 균형 잡힌 출력을 얻을 수 있습니다.

#!/usr/bin/python
def chunks(l, n):
    """ Yield n successive chunks from l.
    """
    newn = int(1.0 * len(l) / n + 0.5)
    for i in xrange(0, n-1):
        yield l[i*newn:i*newn+newn]
    yield l[n*newn-newn:]

l = range(56)
three_chunks = chunks (l, 3)
print three_chunks.next()
print three_chunks.next()
print three_chunks.next()

어떤 출력 :

[0, 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, 36, 37]
[38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55]


답변

n요소를 대략 k청크 로 나눈 경우 n % k다른 요소보다 청크 1 요소를 더 크게 만들어 추가 요소를 배포 할 수 있습니다.

다음 코드는 청크 길이를 제공합니다.

[(n // k) + (1 if i < (n % k) else 0) for i in range(k)]

예 : n=11, k=3결과[4, 4, 3]

그런 다음 청크의 시작 표시를 쉽게 계산할 수 있습니다.

[i * (n // k) + min(i, n % k) for i in range(k)]

예 : n=11, k=3결과[0, 4, 8]

i+1th 청크를 경계로 사용하면 len 이있는 i목록의 청크 가ln

l[i * (n // k) + min(i, n % k):(i+1) * (n // k) + min(i+1, n % k)]

마지막 단계로 목록 이해를 사용하여 모든 청크에서 목록을 만듭니다.

[l[i * (n // k) + min(i, n % k):(i+1) * (n // k) + min(i+1, n % k)] for i in range(k)]

예 : n=11, k=3, l=range(n)결과[range(0, 4), range(4, 8), range(8, 11)]


답변

이것은 단일 표현식으로 분할을 수행합니다.

>>> myList = range(18)
>>> parts = 5
>>> [myList[(i*len(myList))//parts:((i+1)*len(myList))//parts] for i in range(parts)]
[[0, 1, 2], [3, 4, 5, 6], [7, 8, 9], [10, 11, 12, 13], [14, 15, 16, 17]]

이 예의 목록은 크기가 18이며 ​​5 개 부분으로 나뉩니다. 부품의 크기는 하나 이상의 요소가 다릅니다.