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

Jam*_*pam 1 python iteration list

今天我接受了一次采访,我被要求将列表列表打印到一个列表中而不使用任何for或while循环,但是你可以使用其他内置函数.

这是清单:

>>> myList = [[[1,2,3],[4,5],[6,7,8,9]]]
>>> myList
[[[1, 2, 3], [4, 5], [6, 7, 8, 9]]]
>>>
Run Code Online (Sandbox Code Playgroud)

输出将是[1, 2, 3, 4, 5, 6, 7, 8, 9].

知道如何去做吗?

Mar*_*ers 5

三种选择:

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

    >>> sum(myList[0], [])
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    Run Code Online (Sandbox Code Playgroud)

    这可行,因为sum()它基本上是作为循环实现的:

     def sum(values, start=0):
         total = start
         for value in values:
             total += value
         return total
    
    Run Code Online (Sandbox Code Playgroud)

    如果起始值是列表对象本身,则它与列表串联一起使用.0 + [1, 2, 3]不行,但[] + [1, 2, 3]工作得很好.

  2. 你可以使用reduce()with operator.add(),它基本上是相同的sum(),减去给出起始值的要求:

    from operator import add
    
    reduce(add, myList[0])
    
    Run Code Online (Sandbox Code Playgroud)

    operator.add()如果要不惜一切代价避免进口,可以用lambda a, b: a + b或替换list.__add__.

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

    from operator import iadd
    
    reduce(add, myList[0], [])
    
    Run Code Online (Sandbox Code Playgroud)

    但是这确实需要一个空表开始.

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

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

所有这三个解决方案都需要您使用索引来去除最外面的名单,但你也可以通过一个元素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
Run Code Online (Sandbox Code Playgroud)

并比较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
Run Code Online (Sandbox Code Playgroud)

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

def flatten(lst):
    try:
        return flatten(sum(lst, []))
    except TypeError:
        return lst
Run Code Online (Sandbox Code Playgroud)

演示:

>>> 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]
Run Code Online (Sandbox Code Playgroud)