다른 답변에 대한 비판 :
이 답변 중 어느 것도 고른 크기의 청크가 아니며 끝 부분에 런트 청크가 남으므로 완전히 균형이 맞지 않습니다. 이러한 기능을 사용하여 작업을 배포하는 경우 다른 작업보다 먼저 마무리 작업이 완료 될 수 있으므로 다른 작업을 계속하는 동안 아무 작업도 수행하지 않아도됩니다.
예를 들어, 현재 최상위 답변은 다음과 같이 끝납니다.
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74]]
나는 결국 그 런트를 싫어한다!
다른 사람 같은 list(grouper(3, xrange(7)))
, 그리고 chunk(xrange(7), 3)
모두 반환 : [(0, 1, 2), (3, 4, 5), (6, None, None)]
. 의 None
의견은 단지 패딩이며 오히려 우아하지 않습니다. 그들은 iterables를 고르게 청크하지 않습니다.
왜 더 잘 나눌 수 없습니까?
내 솔루션
여기에 내가 (교체 파이썬 3 주 생산에 사용했던 함수에서 적응 균형 잡힌 솔루션의 xrange
와 함께 range
) :
def baskets_from(items, maxbaskets=25):
baskets = [[] for _ in xrange(maxbaskets)] # in Python 3 use range
for i, item in enumerate(items):
baskets[i % maxbaskets].append(item)
return filter(None, baskets)
그리고 목록에 넣으면 똑같은 발전기를 만들었습니다.
def iter_baskets_from(items, maxbaskets=3):
'''generates evenly balanced baskets from indexable iterable'''
item_count = len(items)
baskets = min(item_count, maxbaskets)
for x_i in xrange(baskets):
yield [items[y_i] for y_i in xrange(x_i, item_count, baskets)]
마지막으로 위의 모든 함수가 주어진 순서대로 요소를 연속적인 순서로 반환한다는 것을 알았습니다.
def iter_baskets_contiguous(items, maxbaskets=3, item_count=None):
'''
generates balanced baskets from iterable, contiguous contents
provide item_count if providing a iterator that doesn't support len()
'''
item_count = item_count or len(items)
baskets = min(item_count, maxbaskets)
items = iter(items)
floor = item_count // baskets
ceiling = floor + 1
stepdown = item_count % baskets
for x_i in xrange(baskets):
length = ceiling if x_i < stepdown else floor
yield [items.next() for _ in xrange(length)]
산출
테스트하려면 :
print(baskets_from(xrange(6), 8))
print(list(iter_baskets_from(xrange(6), 8)))
print(list(iter_baskets_contiguous(xrange(6), 8)))
print(baskets_from(xrange(22), 8))
print(list(iter_baskets_from(xrange(22), 8)))
print(list(iter_baskets_contiguous(xrange(22), 8)))
print(baskets_from('ABCDEFG', 3))
print(list(iter_baskets_from('ABCDEFG', 3)))
print(list(iter_baskets_contiguous('ABCDEFG', 3)))
print(baskets_from(xrange(26), 5))
print(list(iter_baskets_from(xrange(26), 5)))
print(list(iter_baskets_contiguous(xrange(26), 5)))
출력되는 내용 :
[[0], [1], [2], [3], [4], [5]]
[[0], [1], [2], [3], [4], [5]]
[[0], [1], [2], [3], [4], [5]]
[[0, 8, 16], [1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20], [5, 13, 21], [6, 14], [7, 15]]
[[0, 8, 16], [1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20], [5, 13, 21], [6, 14], [7, 15]]
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17], [18, 19], [20, 21]]
[['A', 'D', 'G'], ['B', 'E'], ['C', 'F']]
[['A', 'D', 'G'], ['B', 'E'], ['C', 'F']]
[['A', 'B', 'C'], ['D', 'E'], ['F', 'G']]
[[0, 5, 10, 15, 20, 25], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
[[0, 5, 10, 15, 20, 25], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
[[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]]
연속 생성기는 다른 두 패턴과 동일한 길이 패턴으로 청크를 제공하지만 항목은 모두 순서대로 나열되며 개별 요소 목록을 분할 할 수있는만큼 균일하게 분할됩니다.