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

时间:2013-09-05 17:26:46

标签: python list

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

m = [1, 2, 3]
n = [4, 5, 6]
o = [7, 8, 9]

然后我们拨打print join_lists(m, n, o),它将返回[1, 2, 3, 4, 5, 6, 7, 8, 9]。我意识到我应该使用*args作为join_lists中的参数,但不确定如何连接任意数量的列表。感谢。

6 个答案:

答案 0 :(得分:15)

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

标准工具为itertools.chain

def concatenate(*lists):
    return itertools.chain(*lists)

def concatenate(*lists):
    return itertools.chain.from_iterable(lists)

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

如果您坚持“手动”执行此操作,请使用extend

def concatenate(*lists):
    newlist = []
    for l in lists: newlist.extend(l)
    return newlist

<击>

实际上,不要那样使用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

http://ideone.com/Mi3UyL

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


最后,这是使用reduce:

在一行中使用extend(次优)的版本
concatenate = lambda *lists: reduce((lambda a,b: a.extend(b) or a),lists,[])

答案 1 :(得分:11)

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

import operator
from functools import reduce
def concatenate(*lists):
    return reduce(operator.add, lists)

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

from itertools import chain
def concatenate(*lists):
    return chain(*lists)

虽然您也可以直接使用itertools.chain(*iterable_of_lists)

程序方式:

def concatenate(*lists):
    new_list = []
    for i in lists:
        new_list.extend(i)
    return new_list

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

答案 2 :(得分:3)

您可以将sum()与空列表一起用作start参数:

def join_lists(*lists):
    return sum(lists, [])

例如:

>>> join_lists([1, 2, 3], [4, 5, 6])
[1, 2, 3, 4, 5, 6]

答案 3 :(得分:0)

这似乎工作正常:

def join_lists(*args):
    output = []
    for lst in args:
        output += lst
    return output

它返回一个包含以前列表中所有项目的新列表。使用+不适合这种列表处理吗?

答案 4 :(得分:-1)

另一种方式:

>>> m = [1, 2, 3]
>>> n = [4, 5, 6]
>>> o = [7, 8, 9]
>>> p = []
>>> for (i, j, k) in (m, n, o):
...     p.append(i)
...     p.append(j)
...     p.append(k)
... 
>>> p
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> 

答案 5 :(得分:-1)

或者你可能是合乎逻辑的,使变量(这里'z')等于传递给'join_lists'函数的第一个列表 然后将列表中的项目(而不是列表本身)分配给新列表,然后您可以添加其他列表的元素:

m = [1, 2, 3]
n = [4, 5, 6]
o = [7, 8, 9]

def join_lists(*x):
    z = [x[0]]
    for i in range(len(z)):
        new_list = z[i]
    for item in x:
        if item != z:
            new_list += (item)
    return new_list

然后

  

print(join_lists(m,n,o)

会输出:

  

[1,2,3,4,5,6,7,8,9]