今天我接受了一次采访,我被要求在不使用任何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]
。
知道如何解决这个问题吗?
答案 0 :(得分:5)
三个选项:
您可以对嵌套列表求和; 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]
答案 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))