4

What would be the most pythonic way to convert a list like:

mylist = [0,1,2,3,4,5,6,7,8]

into chunks of n elements that always start with the last element of the previous chunk. The last element of the last chunk should be identical to the first element of the first chunk to make the data structure circular. Like:

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

under the assumption that len(mylist) % (n-1) == 0 . So that it always works nicely.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Goswin Rothenthal
  • 2,244
  • 1
  • 19
  • 32

2 Answers2

6

What about the straightforward solution?

splitlists = [mylist[i:i+n] for i in range(0, len(mylist), n-1)]
splitlists[-1].append(splitlists[0][0])
orlp
  • 112,504
  • 36
  • 218
  • 315
0

A much less straightforward solution involving numpy (for the sake of overkill):

from numpy import arange, roll, column_stack

n = 4    
values = arange(10, 26)  
# values -> [10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25]

idx = arange(0, values.size, n)   # [ 0  4  8 12]
idx = roll(idx, -1)               # [ 4  8 12  0] 

col = values[idx]                 # [14 18 22 10]

values = column_stack( (values.reshape(n, -1), col) )

[[10 11 12 13 14]
 [14 15 16 17 18]
 [18 19 20 21 22]
 [22 23 24 25 10]]
gvalkov
  • 3,977
  • 30
  • 31
  • is there any benefit in this ? – Goswin Rothenthal Sep 06 '12 at 11:50
  • It depends. If you use the default array dtype (int64) the pure python solution performs as well as the numpy one. As you start decreasing the integer size, you begin to see significant improvements. See: https://gist.github.com/3655860 – gvalkov Sep 06 '12 at 13:00