在Python中连接函数中的任意数量的列表

ali*_*boy 9 python list

我希望编写join_lists函数来获取任意数量的列表并将它们连接起来.例如,如果输入是

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

然后我们打电话print join_lists(m, n, o),它会回来[1, 2, 3, 4, 5, 6, 7, 8, 9].我意识到我应该使用*args作为参数join_lists,但不知道如何连接任意数量的列表.谢谢.

Mar*_*cin 16

虽然你可以使用__add__顺序调用的东西,但这是非常错误的事情(对于初学者,你最终创建的新列表与输入中的列表一样多,最终会产生二次复杂度).

标准工具是itertools.chain:

def concatenate(*lists):
    return itertools.chain(*lists)
Run Code Online (Sandbox Code Playgroud)

要么

def concatenate(*lists):
    return itertools.chain.from_iterable(lists)
Run Code Online (Sandbox Code Playgroud)

这将返回一个生成器,它按顺序生成列表的每个元素.如果您需要它作为列表,请使用list:list(itertools.chain.from_iterable(lists))

如果你坚持"手工"这样做,那么使用extend:

def concatenate(*lists):
    newlist = []
    for l in lists: newlist.extend(l)
    return newlist
Run Code Online (Sandbox Code Playgroud)

实际上,不要那样使用extend- 它仍然效率低下,因为它必须继续扩展原始列表."正确"的方式(它仍然是错误的方式):

def concatenate(*lists):
    lengths = map(len,lists)
    newlen = sum(lengths)
    newlist = [None]*newlen
    start = 0
    end = 0
    for l,n in zip(lists,lengths):
        end+=n
        newlist[start:end] = list
        start+=n
    return newlist
Run Code Online (Sandbox Code Playgroud)

http://ideone.com/Mi3UyL

您会注意到,这仍然会执行与列表中的总插槽一样多的复制操作.所以,这并不比使用更好list(chain.from_iterable(lists)),并且可能更糟糕,因为list可以在C级别使用优化.


最后,这里是一个使用extend(次优)在一行中的版本,使用reduce:

concatenate = lambda *lists: reduce((lambda a,b: a.extend(b) or a),lists,[])
Run Code Online (Sandbox Code Playgroud)


rlm*_*lms 11

一种方式是这个(使用reduce),因为我目前感觉功能:

import operator
from functools import reduce
def concatenate(*lists):
    return reduce(operator.add, lists)
Run Code Online (Sandbox Code Playgroud)

然而,在Marcin的答案中给出了一种更好的功能方法:

from itertools import chain
def concatenate(*lists):
    return chain(*lists)
Run Code Online (Sandbox Code Playgroud)

虽然你不妨itertools.chain(*iterable_of_lists)直接使用.

程序方式:

def concatenate(*lists):
    new_list = []
    for i in lists:
        new_list.extend(i)
    return new_list
Run Code Online (Sandbox Code Playgroud)

高尔夫版本:( j=lambda*x:sum(x,[])实际上不使用此版本).

  • @alittleboy标准库是一个基本工具. (4认同)
  • 第一种形式将具有二次复杂性,并创建n个中间列表. (3认同)