今天我接受了一次面试,我被要求在不使用任何 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]。
知道怎么做吗?
请您参考如下方法:
三个选项:
您可以对嵌套列表求和;
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]可以正常工作。你可以使用
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], [])但这确实需要一个空列表作为开始。
您可以使用
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]
