今天,我有一个采访,我被要求打印清单列表到一个单独的列表,而无需使用任何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]
不知道如何去这件事吗?
今天,我有一个采访,我被要求打印清单列表到一个单独的列表,而无需使用任何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]
如果我们假设没有允许进口,而我们仍然在2.7.x,
reduce(lambda x,y:x+y,*myList)
这个问题,使得平面列表进行列表,一直在深入分析了快速搜索显示: 制作一个平面列表出Python列表的列表 ,虽然在该线程有什么功能,您可以使用没有限制,他们答案进入有关使用不同方法的时间复杂度非常详细。 这是很重要的,因为它可能是在接受采访时跟进的问题。
myList = [[[1,2,3],[4,5],[6,7,8,9]]]
sum(myList[0], [])
产量
[1, 2, 3, 4, 5, 6, 7, 8, 9]
使用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]
尝试这个
import itertools
list(itertools.chain(*mylist))