2024-05-13 10:08:34 发布
网友
今天我参加了一个面试,我被要求将一个列表列表打印成一个列表,而不使用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, 2, 3, 4, 5, 6, 7, 8, 9]
你知道怎么做吗?在
如果我们假设不允许进口,而且我们仍然使用2.7.x
reduce(lambda x,y:x+y,*myList)
快速搜索显示,这个问题,从列表中生成一个平面列表,已经被深入地分析过:Making a flat list out of list of lists in Python虽然在这个线程中,您可以使用什么函数没有限制,但是他们的回答非常详细地说明了使用不同方法的时间复杂性。这很重要,因为这可能是面试中的后续问题。在
三种选择:
可以对嵌套列表求和;^{}接受第二个参数,即起始值,将其设置为空列表:
>>> sum(myList[0], []) [1, 2, 3, 4, 5, 6, 7, 8, 9]
这是因为sum()实际上是作为一个循环实现的:
sum()
如果起始值是list对象本身,那么它可以与list连接。0 + [1, 2, 3]不能工作,但是{}工作得很好。
0 + [1, 2, 3]
您可以将^{}与^{}一起使用,这与sum()基本相同,但不需要提供起始值:
from operator import add reduce(add, myList[0])
如果要不惜一切代价避免进口,可以用lambda a, b: a + b或list.__add__代替{}。在
lambda a, b: a + b
list.__add__
随着嵌套输入列表的增长,^{}(in place add,for list相当于list.extend())将迅速成为一个更快的选项:
list.extend()
from operator import iadd reduce(add, myList[0], [])
但是这个确实需要一个空列表来开始。
您可以使用^{}链接列表:
>>> from itertools import chain >>> list(chain.from_iterable(myList[0])) [1, 2, 3, 4, 5, 6, 7, 8, 9]
这三种解决方案都要求您使用索引来删除最外层的列表,尽管您也可以将myList中的一个元素作为单个参数传递给带有list(chain.from_iterable(*myList))的{}。在
myList
list(chain.from_iterable(*myList))
在这些选项中,reduce(add, ...)是最快的:
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与{}:
iadd
>>> 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]
myList = [[[1,2,3],[4,5],[6,7,8,9]]] sum(myList[0], [])
输出
如果我们假设不允许进口,而且我们仍然使用2.7.x
快速搜索显示,这个问题,从列表中生成一个平面列表,已经被深入地分析过:Making a flat list out of list of lists in Python虽然在这个线程中,您可以使用什么函数没有限制,但是他们的回答非常详细地说明了使用不同方法的时间复杂性。这很重要,因为这可能是面试中的后续问题。在
三种选择:
可以对嵌套列表求和;^{} 接受第二个参数,即起始值,将其设置为空列表:
这是因为
^{pr2}$sum()
实际上是作为一个循环实现的:如果起始值是list对象本身,那么它可以与list连接。}工作得很好。
0 + [1, 2, 3]
不能工作,但是{您可以将^{} 与^{} 一起使用,这与
sum()
基本相同,但不需要提供起始值:如果要不惜一切代价避免进口,可以用}。在
lambda a, b: a + b
或list.__add__
代替{随着嵌套输入列表的增长,^{} (in place add,for list相当于
list.extend()
)将迅速成为一个更快的选项:但是这个确实需要一个空列表来开始。
您可以使用^{} 链接列表:
这三种解决方案都要求您使用索引来删除最外层的列表,尽管您也可以将}。在
myList
中的一个元素作为单个参数传递给带有list(chain.from_iterable(*myList))
的{在这些选项中,
reduce(add, ...)
是最快的:比较}:
iadd
与{您可以使用递归来避免使用循环,使其适用于任意嵌套的列表:
演示:
输出
^{pr2}$相关问题 更多 >
编程相关推荐