简体   繁体   中英

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?

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]

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.

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

sum(myList[0], [])

Output

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

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]

try this

import itertools

list(itertools.chain(*mylist))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM