One may want to do the contrary of flattening a list of lists, like here: I was wondering how you can convert a flat list into a list of lists.
In numpy you could do
Another way to create a list of lists can be simplified as shown below:
>>>MyList = ['a','b','c','d','e','f']
# Calculate desired row/col
>>>row = 3
>>>col = 2
>>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)]
>>>NewList
[['a', 'b', 'c'], ['d', 'e', 'f']]
This can method can be extended to produce any row and column size. If you select row and column values such that row*col >len(MyList)
, the sublist (row) containing the last value in MyList
will end there, and NewList
will simply be filled with the appropriate number of empty lists to satisfy the row/col specifications
>>>MyList = ['a','b','c','d','e','f','g','h']
>>>row = 3
>>>col = 3
>>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)]
>>>NewList
[['a', 'b', 'c'], ['d', 'e', 'f'], ['g','h']]
>>>row = 4
>>>col = 4
>>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)]
[['a', 'b', 'c', 'd'], ['e', 'f', 'g','h'], [], []]
This is usually done using the grouper recipe from the itertools documentation:
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return itertools.izip_longest(fillvalue=fillvalue, *args)
Example:
>>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> list(grouper(2, my_list))
[('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', None)]
If one prefers a list of lists, rather than a list of tuples from a flat list, then one could do this:
a = range(20) # sample starting list
b = [] # new list
c = [] # alternate new list
# ny is length of new list. nx length of each list within it
nx = 5; ny = 4
bb = 0; ee = bb + nx # option one: sliding indeces for slices.
for ii in range(ny-1):
bb += nx
ee += nx
b.append(a[bb:ee])
c.append(a[slice(ii*nx,nx*(ii+1))]) # option two, use slice()
(I've played around with shrinking the whole for loop into one line with list comprehensions, but have not been successful. the way I've used it, slice() can almost get you there.) One possible advantage of these approaches over the others mentioned is that if your original, flat list is not an even multiple of the dimensions of your new, desired list of lists, you won't lose any data. The caveat is that the last list will be shorter than all the others, as it will contain the "leftovers". granted, neither of these methods strikes me as very pythonic.
>>> l = ['a', 'b', 'c', 'd', 'e', 'f']
>>> zip(*[iter(l)]*2)
[('a', 'b'), ('c', 'd'), ('e', 'f')]
As it has been pointed out by @Lattyware, this only works if there are enough items in each argument to the zip
function each time it returns a tuple. If one of the parameters has less items than the others, items are cut off eg.
>>> l = ['a', 'b', 'c', 'd', 'e', 'f','g']
>>> zip(*[iter(l)]*2)
[('a', 'b'), ('c', 'd'), ('e', 'f')]
If this is the case then it is best to use the solution by @Sven Marnach
How does zip(*[iter(s)]*n) work