Skip to main content
 首页 » 编程设计

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

2025年05月04日14zengkefu

今天我接受了一次面试,我被要求在不使用任何 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]。

知道怎么做吗?

请您参考如下方法:

三个选项:

  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 + b 或者 list.__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] 
    

这三种解决方案都要求您使用索引来删除最外层的列表,尽管您也可以将 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 

并比较 iadd 与 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 

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

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]