ActiveState Code

Recipe 426331: Split into roughly equal sized columns


Break a list into roughly equaly sized 'columns', e.g. for display in a table.

Python
1
2
3
4
5
6
7
8
def colsplit(l, cols):
    rows = len(l) / cols
    if len(l) % cols:
        rows += 1
    m = []
    for i in range(rows):
        m.append(l[i::rows])
    return m

Discussion

See also: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/425397

Recently a collegue had to split a list of content items into columns, from top to bottom, left to right, for rendering in a HTML table. Example table, for a list of items from 1 to 10:

1 5 9 2 6 10 3 7 4 8

Together we came to this recipe. The trick was to use the third parameter in the slice notation (thanks Guido Wesdorp for the helpful hint!).

>>> l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> columns = 3
>>> colsplit(l, columns)
[[1, 5, 9], [2, 6, 10], [3, 7], [4, 8]]
>>> l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> columns = 6
[[1, 4, 7, 10, 13], [2, 5, 8, 11, 14], [3, 6, 9, 12]]

Comments

  1. 1. At 9:48 a.m. on 30 jun 2005, Marc Keller said:

    a light modification. def colsplit(l, cols):

    ....rows,r = divmod(len(l),cols)

    ....rows += (r!=0)

    ....m = []

    ....for i in range(rows):

    ........m.append(l[i::rows])

    ....return m

  2. 2. At 8:54 p.m. on 30 jun 2005, Paul Watson said:

    To skew or not to skew... This recepie is quite nice for dividing a sequence for the presentation needed. However, the last sequence could end up containing only one item. If minimizing skew between result sequences is important, see the recepies the author referenced in the discussion.

Sign in to comment