如何在不使用任何for或while循环的情况下将列表列表打印到python中的单个列表中?

时间:2013-12-05 14:26:17

标签: python list iteration

今天我接受了一次采访,我被要求在不使用任何for或while循环的情况下将列表列表打印到一个列表中,但您可以使用其他内置函数。

以下是清单:

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

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

知道如何解决这个问题吗?

5 个答案:

答案 0 :(得分:5)

三个选项:

  1. 您可以对嵌套列表求和; sum()接受第二个参数,一个起始值,将其设置为空列表:

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

    这是有效的,因为sum()基本上是作为循环实现的:

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

    与列表连接一起使用,前提是起始值是列表对象本身。 0 + [1, 2, 3]无效,但[] + [1, 2, 3]效果很好。

  2. 您可以将reduce()operator.add()一起使用,这与sum()基本相同,减去了提供起始值的要求:

    from operator import add
    
    reduce(add, myList[0])
    
    如果要不惜一切代价避免进口,

    operator.add()可以替换为lambda a, b: a + blist.__add__

    随着嵌套输入列表的增长,operator.iadd()(就地添加,对于列表等同于list.extend())将迅速成为更快的选择:

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

    需要一个空列表才能开始。

  3. 您可以使用itertools.chain.from_iterable()链接列表:

    >>> from itertools import chain
    >>> list(chain.from_iterable(myList[0]))
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
  4. 所有三个解决方案都要求您使用索引来删除最外面的列表,尽管您也可以将myList中的一个元素作为单个参数传递给chain.from_iterable() list(chain.from_iterable(*myList))

    在这些选项中,reduce(add, ...)是最快的:

    >>> 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
    

    并比较iaddadd

    >>> 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
    

    您可以使用递归来避免使用循环,以使其适用于任意嵌套列表:

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

    演示:

    >>> 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]
    

答案 1 :(得分:4)

如果我们假设不允许导入,并且我们仍然在2.7.x,

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

快速搜索显示这个问题,从列表中列出一个平面列表,已经进行了深入分析:Making a flat list out of list of lists in Python虽然在该主题中没有对可以使用的功能进行限制,但他们的回答是关于使用不同方法的时间复杂性的详细信息。这非常重要,因为它可能是访谈中的后续问题。

答案 2 :(得分:2)

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

sum(myList[0], [])

<强>输出

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

答案 3 :(得分:1)

使用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]

答案 4 :(得分:1)

试试这个

import itertools

list(itertools.chain(*mylist))