splitting a list into n groups

Eddie Corns eddie at holyrood.ed.ac.uk
Thu Oct 9 07:17:12 EDT 2003


Peter Otten <__peter__ at web.de> writes:

>Eddie Corns wrote:

>> Rajarshi Guha <rajarshi at presidency.com> writes:
>> 
>>>Hi,
>>>  is there an efficient (pythonic) way in which I could split a list into
>>>say 5 groups? By split I mean the the first x members would be one group,
>>>the next x members another group and so on 5 times. (Obviously x =
>>>lengthof list/5)
>> 
>> How about:
>> 
>> ------------------------------------------------------------
>> def span (x, n):
>>     return range(0, x, n)
>> 
>> def group (l, num):
>>     n = (len(l)/num) + 1
>>     return [l[s:s+n] for s in span (len(l), n)]
>> 
>> # test cases
>> l1 = range(100)
>> print group (l1, 5)
>> print group (l1, 6)
>> print group (l1, 4)
>> ------------------------------------------------------------

>More test cases :-)

>for k in range(20):
>    l1 = range(k)
>    lol = group(l1, 5)
>    print len(lol), lol

>0 []
>1 [[0]]
>2 [[0], [1]]
>3 [[0], [1], [2]]
>4 [[0], [1], [2], [3]]
>3 [[0, 1], [2, 3], [4]]
>3 [[0, 1], [2, 3], [4, 5]]
>4 [[0, 1], [2, 3], [4, 5], [6]]
>4 [[0, 1], [2, 3], [4, 5], [6, 7]]
>5 [[0, 1], [2, 3], [4, 5], [6, 7], [8]]
>4 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
>4 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]
>4 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
>5 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12]]
>5 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13]]
>4 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14]]
>4 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]
>5 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16]]
>5 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17]]
>5 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17,
>18]]

Critiscism first thing in the morning!, luckily I got out of bed on the right
side this morning.

def span (x, n):
    return range(0, x, n)

def group (l, num):
    n = ((len(l))/num) + 1
    res = [l[s:s+n] for s in span (len(l), n)]
    return res + [None]*(num-len(res))

# test cases
for k in range(1,20):
    l1 = range(k)
    lol = group(l1, 5)
    print len(lol), lol

5 [[0], None, None, None, None]
5 [[0], [1], None, None, None]
5 [[0], [1], [2], None, None]
5 [[0], [1], [2], [3], None]
5 [[0, 1], [2, 3], [4], None, None]
5 [[0, 1], [2, 3], [4, 5], None, None]
5 [[0, 1], [2, 3], [4, 5], [6], None]
5 [[0, 1], [2, 3], [4, 5], [6, 7], None]
5 [[0, 1], [2, 3], [4, 5], [6, 7], [8]]
5 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9], None]
5 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10], None]
5 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], None]
5 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12]]
5 [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13]]
5 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14], None]
5 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], None]
5 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16]]
5 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17]]
5 [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18]]


With new improved boundary condition checking as well.  The OP can put in
checks for 0 if it makes any sense.  Short lists will need more sophisticated
handling to avoid results like:

[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14], None]

We shouldn't expect too much from 3 lines of code, not even in Python.

Eddie




More information about the Python-list mailing list