11

我希望编写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,但不确定如何连接任意数量的列表。谢谢。

4

6 回答 6

18

尽管您可以使用__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

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


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

concatenate = lambda *lists: reduce((lambda a,b: a.extend(b) or a),lists,[])
于 2013-09-05T17:34:02.630 回答
15

一种方法是(使用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,[])实际上不要使用它)。

于 2013-09-05T17:29:03.960 回答
2

您可以使用sum()空列表作为start参数:

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

例如:

>>> join_lists([1, 2, 3], [4, 5, 6])
[1, 2, 3, 4, 5, 6]
于 2013-09-05T17:30:44.147 回答
0

另一种方式:

>>> 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]
>>> 
于 2013-09-05T17:43:38.657 回答
0

这似乎工作得很好:

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

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

于 2014-01-25T23:41:38.310 回答
-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

然后

打印 (join_lists(m, n ,o)

会输出:

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

于 2013-10-29T15:04:28.377 回答