4

I have a large list of lists, for example:

list = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]

I would like to combine every 5 lists into one list of elements and so on. I am having total of 150995 lists inside a list.

Expected output:

new_list = [['a' , 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

I tried with below code. but it is flattens to one list.

list(zip(*list)[0])

How can I do this?

1
  • would flatten + group as evenly sized chunks would do? your lists contain just 1 element? or can contain something else? Commented Jul 29, 2018 at 20:47

7 Answers 7

3

you basically want to group evenly sized chunks of lists. It's possible using itertools.chain and slicing with range and a step of 5

import itertools

lst = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]

result = [list(itertools.chain.from_iterable(itertools.islice(lst,i,i+5))) for i in range(0,len(lst),5)]


print(result)

result:

[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

notes:

  • using itertools.islice avoids a standard lst[i:i+5] slicing that creates a useless list object
  • it works even when the number of elements isn't divisible by 5.
1

Given:

>>> li = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]

You can do:

>>> list(map(list, zip(*[iter([e for sublist in li for e in sublist])]*5)))
[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

Or,

>>> [[e for sublist in lst[i:i+5] for e in sublist] for i in range(0,len(lst),5)]
[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]
3
  • how does map function takes "list" keyword as first argument? Commented Jul 29, 2018 at 21:09
  • 2
    Map calls the first function on all the elements of the second function and returns a generator. list isn't a keyword, it's a function.
    – ggorlen
    Commented Jul 29, 2018 at 21:18
  • @karthikeayan list is not a keyword. It is merely the name of a built-in function. It is a normal variable in that respect, you can assign whatever you want to it: list = "you shouldn't do this" Commented Jul 30, 2018 at 0:38
0

This solution is convenient since it uses nothing besides numpy

If your list always has elements divisible by 5, then

import numpy as np
oldlist = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]
newlist = np.reshape(oldlist,(len(oldlist)//5,5)).T.tolist()

newlist will have your desired output of

[['a' , 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]
0

Use itertools.chain to flatten the list and itertools.zip_longest to group the elemensts in chunks of 5

>>> from itertools import zip_longest, chain
>>> n = 5
>>> list(zip_longest(*[chain(*List)]*n))    
[('a', 'b', 'c', '1234', 'd'), ('e', 'g', 'h', 'i', '56')]

If you are not happy with the result being list of tuples, you can convert the individual elements from tuple to list using map

>>> list(map(list, zip_longest(*[chain(*List)]*5)))
[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]
0

Many good solutions already. I just wanted to add one more possiblity that is using a custom Iterator like so:

from itertools import chain


class MyIter:
    def __init__(self, lists,n_first):
        self.lists = lists
        self.index = 0
        self.n_first = n_first

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < len(self.lists):

            temp = list(chain(*self.lists[self.index:min(self.index+self.n_first,len(self.lists))]))
            self.index += self.n_first
            return temp
        else:
            raise StopIteration

_list = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]

print(list(MyIter(_list,5)))
0

Assuming the len(list) is a multiple of 5, the following solution works:

list = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]
row = int(len(list)/5)
new_list = [i.tolist() for i in np.array(list).reshape((row,5))]
print (new_list)

resulting in

[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]
1
  • Apparently. I was working on it while you already posted. But just another road to reach the same destination ;)
    – Sheldore
    Commented Jul 29, 2018 at 21:14
0

Here's a non-library list comprehension solution:

>>> L = [['a'], ['b'], ['c'], ['1234'], ['d'], ['e'], ['g'], ['h'], ['i'], ['56']]
>>> [[j[0] for j in L[i:i+5]] for i in range(0, len(L), 5)]
[['a', 'b', 'c', '1234', 'd'], ['e', 'g', 'h', 'i', '56']]

By the way, calling your list list redefines a builtin function.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.