James Sapam
James Sapam

Reputation: 16940

How to print list of list into one single list in python without using any for or while loop?

Today I had an interview and I was asked to print a list of list into one single list without using any for or while loop but you can use other built in function.

Here is the list:

>>> myList = [[[1,2,3],[4,5],[6,7,8,9]]]
>>> myList
[[[1, 2, 3], [4, 5], [6, 7, 8, 9]]]
>>>

The output will be [1, 2, 3, 4, 5, 6, 7, 8, 9].

Any idea how to go about this?

Upvotes: 1

Views: 224

Answers (5)

fahad
fahad

Reputation: 3179

try this

import itertools

list(itertools.chain(*mylist))

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1123710

Three options:

  1. You could sum the nested lists; sum() takes a second argument, a starting value, set that to an empty list:

    >>> sum(myList[0], [])
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    This works because sum() is essentially implemented as a loop:

     def sum(values, start=0):
         total = start
         for value in values:
             total += value
         return total
    

    which works with list concatenation, provided the start value is a list object itself. 0 + [1, 2, 3] would not work, but [] + [1, 2, 3] works just fine.

  2. You could use reduce() with operator.add(), which is essentially the same as sum(), minus the requirement to give a start value:

    from operator import add
    
    reduce(add, myList[0])
    

    operator.add() could be replaced with lambda a, b: a + b or with list.__add__ if imports are to be avoided at all cost.

    As the nested input list grows, operator.iadd() (in-place add, for lists the equivalent of list.extend()) will rapidly become a faster option:

    from operator import iadd
    
    reduce(add, myList[0], [])
    

    but this does need an empty list to start with.

  3. You could chain the lists using itertools.chain.from_iterable():

    >>> from itertools import chain
    >>> list(chain.from_iterable(myList[0]))
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    

All three solutions require that you use indexing to remove the outermost list, although you can also pass the one element in myList as a single argument to chain.from_iterable() with list(chain.from_iterable(*myList)) as well.

Of these options, reduce(add, ...) is the fastest:

>>> timeit.timeit("sum(myList[0], [])", 'from __main__ import myList')
1.2761731147766113
>>> timeit.timeit("reduce(add, myList[0])", 'from __main__ import myList; from operator import add')
1.0545191764831543
>>> timeit.timeit("reduce(lambda a, b: a.extend(b) or a, myList[0], [])", 'from __main__ import myList')
2.225532054901123
>>> timeit.timeit("list(chain.from_iterable(myList[0]))", 'from __main__ import myList; from itertools import chain')
2.0208170413970947

and comparing iadd versus add:

>>> timeit.timeit("reduce(add, myList[0])", 'from __main__ import myList; from operator import add')
0.9298770427703857
>>> timeit.timeit("reduce(iadd, myList[0], [])", 'from __main__ import myList; from operator import iadd')
1.178157091140747
>>> timeit.timeit("reduce(add, myListDoubled)", 'from __main__ import myList; myListDoubled = myList[0] + myList[0]; from operator import add')
2.3597090244293213
>>> timeit.timeit("reduce(iadd, myListDoubled, [])", 'from __main__ import myList; myListDoubled = myList[0] + myList[0]; from operator import iadd')
1.730151891708374

You could use recursion to avoid using a loop, to make this work for arbitrarily nested lists:

def flatten(lst):
    try:
        return flatten(sum(lst, []))
    except TypeError:
        return lst

Demo:

>>> flatten(myList)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> flatten(myList + myList)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Upvotes: 5

William Denman
William Denman

Reputation: 3164

If we assume no imports allowed and that we are still on 2.7.x,

reduce(lambda x,y:x+y,*myList)

A quick search show that this question, making a flat list out of lists, has been analyzed in depth: Making a flat list out of list of lists in Python and although in that thread there is no restriction on what functions you can use, they answer goes into great detail about the time complexity of using different methods. This is quite important, as it could be the follow up question in an interview.

Upvotes: 4

koffein
koffein

Reputation: 1882

myList = [[[1,2,3],[4,5],[6,7,8,9]]]

sum(myList[0], [])

Output

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

Upvotes: 2

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 251096

Use itertools.chain.from_iterable:

In [34]: from itertools import chain

In [35]: list(chain.from_iterable(myList[0]))
Out[35]: [1, 2, 3, 4, 5, 6, 7, 8, 9]

Upvotes: 1

Related Questions