如何在Python中连接两个列表?

如何在Python中连接两个列表?

示例:

listone = [1, 2, 3]listtwo = [4, 5, 6]

预期成果:

>>> joinedlist[1, 2, 3, 4, 5, 6]
3956469 次浏览

使用+运算符组合列表:

listone = [1, 2, 3]listtwo = [4, 5, 6]
joinedlist = listone + listtwo

输出:

>>> joinedlist[1, 2, 3, 4, 5, 6]

这很简单,我认为它甚至在该教程中显示:

>>> listone = [1,2,3]>>> listtwo = [4,5,6]>>>>>> listone + listtwo[1, 2, 3, 4, 5, 6]

也可以创建一个生成器,使用#0简单地迭代两个列表中的项目。这允许您将列表(或任何可迭代的)链接在一起进行处理,而无需将项目复制到新列表:

import itertoolsfor item in itertools.chain(listone, listtwo):# Do something with each list item

您可以使用集合来获取唯一值的合并列表

mergedlist = list(set(listone + listtwo))

您还可以使用#0方法将list添加到另一个方法的末尾:

listone = [1,2,3]listtwo = [4,5,6]
listone.extend(listtwo)

如果你想保持原始列表不变,你可以创建一个新的list对象,extend都列出了它:

mergedlist = []mergedlist.extend(listone)mergedlist.extend(listtwo)

值得注意的是,itertools.chain函数接受可变数量的参数:

>>> l1 = ['a']; l2 = ['b', 'c']; l3 = ['d', 'e', 'f']>>> [i for i in itertools.chain(l1, l2)]['a', 'b', 'c']>>> [i for i in itertools.chain(l1, l2, l3)]['a', 'b', 'c', 'd', 'e', 'f']

如果可迭代(元组、列表、生成器等)是输入,则可以使用from_iterable类方法:

>>> il = [['a'], ['b', 'c'], ['d', 'e', 'f']]>>> [i for i in itertools.chain.from_iterable(il)]['a', 'b', 'c', 'd', 'e', 'f']

您可以简单地使用++=运算符,如下所示:

a = [1, 2, 3]b = [4, 5, 6]
c = a + b

或:

c = []a = [1, 2, 3]b = [4, 5, 6]
c += (a + b)

此外,如果您希望合并列表中的值是唯一的,您可以执行以下操作:

c = list(set(a + b))

你可以使用list对象上定义的append()方法:

mergedlist =[]for elem in listone:mergedlist.append(elem)for elem in listtwo:mergedlist.append(elem)

如果您需要合并两个具有复杂排序规则的有序列表,您可能必须像下面的代码一样自己滚动它(使用简单的排序规则以获得易读性 :-) ).

list1 = [1,2,5]list2 = [2,3,4]newlist = []
while list1 and list2:if list1[0] == list2[0]:newlist.append(list1.pop(0))list2.pop(0)elif list1[0] < list2[0]:newlist.append(list1.pop(0))else:newlist.append(list2.pop(0))
if list1:newlist.extend(list1)if list2:newlist.extend(list2)
assert(newlist == [1, 2, 3, 4, 5])

使用Python 3.3+,您可以使用产量从

listone = [1,2,3]listtwo = [4,5,6]
def merge(l1, l2):yield from l1yield from l2
>>> list(merge(listone, listtwo))[1, 2, 3, 4, 5, 6]

或者,如果您想支持任意数量的迭代器:

def merge(*iters):for it in iters:yield from it
>>> list(merge(listone, listtwo, 'abcd', [20, 21, 22]))[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 20, 21, 22]

如果你不能使用加号运算符(+),你可以使用operator导入:

import operator
listone = [1,2,3]listtwo = [4,5,6]
result = operator.add(listone, listtwo)print(result)
>>> [1, 2, 3, 4, 5, 6]

或者,您也可以使用__add__dunder函数:

listone = [1,2,3]listtwo = [4,5,6]
result = list.__add__(listone, listtwo)print(result)
>>> [1, 2, 3, 4, 5, 6]

对于列表数量较少的情况,您可以简单地将列表添加在一起或使用就地解包(在Python-3.5+中可用):

In [1]: listone = [1, 2, 3]...: listtwo = [4, 5, 6]
In [2]: listone + listtwoOut[2]: [1, 2, 3, 4, 5, 6]                                                                                                                                                                                     
In [3]: [*listone, *listtwo]Out[3]: [1, 2, 3, 4, 5, 6]

对于具有更多列表数量的情况,作为更通用的方法,您可以使用itertools模块中的chain.from_iterable()1函数。此外,基于这个答案,此函数是最好的;或者至少也是平坦嵌套列表的非常好的方法。

>>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]>>> import itertools>>> list(itertools.chain.from_iterable(l))[1, 2, 3, 4, 5, 6, 7, 8, 9]

1.请注意,“chain.from_iterable()”在Python 2.6及更高版本中可用。在其他版本中,请使用“chain(*l)”。

如果要以排序形式合并两个列表,可以使用heapq库中的merge函数。

from heapq import merge
a = [1, 2, 4]b = [2, 4, 6, 7]
print list(merge(a, b))

这个问题直接询问加入两个列表。然而,即使您正在寻找加入多个列表的方法(包括加入零列表的情况),它的搜索量也很高。

我认为最好的选择是使用列表推导:

>>> a = [[1,2,3], [4,5,6], [7,8,9]]>>> [x for xs in a for x in xs][1, 2, 3, 4, 5, 6, 7, 8, 9]

您也可以创建生成器:

>>> map(str, (x for xs in a for x in xs))['1', '2', '3', '4', '5', '6', '7', '8', '9']

旧答案

考虑这个更通用的方法:

a = [[1,2,3], [4,5,6], [7,8,9]]reduce(lambda c, x: c + x, a, [])

将输出:

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

请注意,当a[][[1,2,3]]时,这也可以正常工作。

但是,这可以通过itertools更有效地完成:

a = [[1,2,3], [4,5,6], [7,8,9]]list(itertools.chain(*a))

如果你不需要list,而只需要一个可迭代的,省略list()

更新

Patrick Collins在评论中建议的替代方案也适用于您:

sum(a, [])

正如许多人已经指出的那样,如果需要将完全一样的待遇应用于两个列表,那么itertools.chain()就是要走的路。在我的例子中,我有一个标签和一个标志,它们从一个列表到另一个列表是不同的,所以我需要稍微复杂一点的东西。事实证明,在幕后itertools.chain()只是执行以下操作:

for it in iterables:for element in it:yield element

(见https://docs.python.org/2/library/itertools.html),所以我从这里得到了灵感,并按照以下思路写了一些东西:

for iterable, header, flag in ( (newList, 'New', ''), (modList, 'Modified', '-f')):print header + ':'for path in iterable:[...]command = 'cp -r' if os.path.isdir(srcPath) else 'cp'print >> SCRIPT , command, flag, srcPath, mergedDirPath[...]

这里要理解的要点是列表只是可迭代的一个特例,它是像任何其他对象一样的对象;并且python中的for ... in循环可以使用元组变量,因此同时循环多个变量很简单。

Python>=3.5可选:[*l1, *l2]

通过接受PEP 448引入了另一种替代方案,值得一提。

标题为附加解包泛化的PEP在Python中使用带星号的*表达式时通常减少了一些语法限制;有了它,加入两个列表(适用于任何可迭代)现在也可以通过以下方式完成:

>>> l1 = [1, 2, 3]>>> l2 = [4, 5, 6]>>> joined_list = [*l1, *l2]  # unpack both iterables in a list literal>>> print(joined_list)[1, 2, 3, 4, 5, 6]

此功能被定义适用于Python 3.5,但它尚未向后移植到3. x系列中的早期版本。在不受支持的版本中,将引发SyntaxError

与其他方法一样,这也是相应列表中元素的创建浅拷贝


这种方法的上行是您真的不需要列表来执行它;任何可迭代的东西都可以。如PEP中所述:

这也是一种更可读的将迭代求和为列表,例如my_list + list(my_tuple) + list(my_range),现在是相当于[*my_list, *my_tuple, *my_range]

因此,虽然添加+会由于类型不匹配而引发TypeError

l = [1, 2, 3]r = range(4, 7)res = l + r

以下不会:

res = [*l, *r]

因为它将首先解压缩可迭代对象的内容,然后简单地从内容创建list

list(set(listone) | set(listtwo))

上面的代码不保留顺序并从每个列表中删除重复项(但不从连接列表中删除)。

所有可能的方式加入列表,我可以找到

import itertools
A = [1,3,5,7,9] + [2,4,6,8,10]
B = [1,3,5,7,9]B.append([2,4,6,8,10])
C = [1,3,5,7,9]C.extend([2,4,6,8,10])
D = list(zip([1,3,5,7,9],[2,4,6,8,10]))E = [1,3,5,7,9]+[2,4,6,8,10]F = list(set([1,3,5,7,9] + [2,4,6,8,10]))
G = []for a in itertools.chain([1,3,5,7,9], [2,4,6,8,10]):G.append(a)

print("A: " + str(A))print("B: " + str(B))print("C: " + str(C))print("D: " + str(D))print("E: " + str(E))print("F: " + str(F))print("G: " + str(G))

产出

A: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]B: [1, 3, 5, 7, 9, [2, 4, 6, 8, 10]]C: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]D: [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]E: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]F: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]G: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]

组合列表的一种非常简洁的方法是

list_of_lists = [[1,2,3], [4,5,6], [7,8,9]]reduce(list.__add__, list_of_lists)

这给了我们

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

使用一个简单的列表理解:

joined_list = [item for list_ in [list_one, list_two] for item in list_]

它具有使用附加解包泛化的最新方法的所有优点-即您可以以这种方式连接任意数量的不同可迭代对象(例如,列表,元组,范围和生成器)-并且不限于Python 3.5或更高版本。

如果您使用的是NumPy,您可以使用此命令连接两个兼容维度的数组:

numpy.concatenate([a,b])

所以有两个简单的方法。

  1. 使用#0:它从提供的列表创建一个新列表

示例:

In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: a + bOut[3]: [1, 2, 3, 4, 5, 6]
In [4]: %timeit a + b10000000 loops, best of 3: 126 ns per loop
  1. 使用扩展:它将新列表附加到现有列表。这意味着它不会创建单独的列表。

示例:

In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: %timeit a.extend(b)10000000 loops, best of 3: 91.1 ns per loop

因此,我们看到在两种最流行的方法中,extend是有效的。

如何在Python中连接两个列表?

从3.9开始,这些是Python中连接两个(或多个)列表的最流行的stdlib方法。

版本限制就地?推广到N个列表?
a+b-sum([a, b, c], [])1
list(chain(a,b))2>=2.3list(chain(a, b, c))
[*a, *b]3>=3.5[*a, *b, *c]
a += b-
a.extend(b)-

脚注

  1. 由于它的简洁性,这是一个巧妙的解决方案。但是sum以成对的方式执行连接,这意味着这是一个必须为每一步分配二次运算作为内存。DO如果您的列表很大,请不要使用。

  2. 请参见chainchain.from_iterable从文档中。您需要先from itertools import chain。连接在内存中是线性的,所以这是最好的性能和版本兼容性。chain.from_iterable是在2.6中引入的。

  3. 此方法使用其他解包通用(PEP 448),但不能使用泛化到N个列表,除非你自己手动解压缩每个列表。

  4. a += ba.extend(b)对于所有实际目的或多或少是等价的。+=在列表上调用时将在内部调用list.__iadd__,将第一个列表扩展到第二个列表。


性能

2-列表串联1

在此处输入图片描述

这些方法之间没有太大的区别,但这是有道理的,因为它们都具有相同的复杂性顺序(线性)。除了风格问题外,没有特别的理由更喜欢其中一个。

N列表串联

在此处输入图片描述

使用灌流图模块生成了绘图。代码,供您参考。

1.iadd+=)和extend方法是就地操作的,因此每次测试前都必须生成一个副本。为了公平起见,所有方法都有左侧列表的预复制步骤,可以忽略。


对其他解决方案的评论

  • 不要以任何方式、形状或形式直接使用Dunder方法list.__add__。事实上,远离dunder方法,并像设计的那样使用运算符和operator函数。Python已经仔细的语义学融入其中,这比直接调用dunder更复杂。这是一个例子。所以,总结一下,a.__add__(b)=>坏;a + b=>好。

  • 这里的一些答案为成对连接提供了reduce(operator.add, [a, b])-这与sum([a, b], [])相同,只是更冗长。

  • 任何使用set的方法都会删除重复项并失去排序。谨慎使用。

  • for i in b: a.append(i)a.extend(b)更冗长,更慢,a.extend(b)是单函数调用,更惯用。append慢,因为内存分配和增长列表的语义学。类似的讨论参见这里

  • heapq.merge可以工作,但它的用例是在线性时间内合并排序列表。在任何其他情况下使用它都是反模式。

  • #从函数中输入列表元素是一种可以接受的方法,但是chain做得更快更好(它在C中有一个代码路径,所以它很快)。

  • operator.add(a, b)是可以接受的与a + b等效的功能。它的用例主要用于动态方法调度。否则,首选更短且更具可读性的a + b在我看来。YMMV。

 a = [1, 2, 3]b = [4, 5, 6]     
c = a + bprint(c)

产出

>>> [1, 2, 3, 4, 5, 6]

在上面的代码中,“+”运算符用于将两个列表连接成一个列表。

另一种解决方案

 a = [1, 2, 3]b = [4, 5, 6]c = [] # Empty list in which we are going to append the values of list (a) and (b)
for i in a:c.append(i)for j in b:c.append(j)
print(c)

产出

>>> [1, 2, 3, 4, 5, 6]

我假设你想要两种方法中的一种:

保留重复元素

这很简单。只需像字符串一样连接:

def concat_list(l1,l2):l3 = l1+l2return l3

接下来,如果要消除重复元素

def concat_list(l1,l2):l3 = []for i in [l1,l2]:for j in i:if j not in l3:# Check if element exists in final list, if no then add element to listl3.append(j)return l3

您可以在Python中使用Union()函数。

joinedlist = union(listone, listtwo)print(joinedlist)

本质上,它删除了两个列表中的每一个重复项。由于您的列表没有任何重复项,它只是返回两个列表的串联版本。

另一种方式:

>>> listone = [1, 2, 3]>>> listtwo = [4, 5, 6]>>> joinedlist = [*listone, *listtwo]>>> joinedlist[1, 2, 3, 4, 5, 6]>>>

您也可以使用

>>> a = [1, 2, 3]>>> b = [4, 5, 6]>>> sum([a, b], [])[1, 2, 3, 4, 5, 6]>>>

这适用于任何长度和任何元素类型的列表:

>>> a = ['a', 'b', 'c', 'd']>>> b = [1, 2, 3, 4]>>> c = [1, 2]>>> sum([a, b, c], [])['a', 'b', 'c', 'd', 1, 2, 3, 4, 1, 2]>>>

我添加[]的原因是因为start参数默认设置为0,所以它循环遍历列表并添加到start,但是0 + [1, 2, 3]会给出错误,所以如果我们将start设置为[]。它会添加到[][] + [1, 2, 3]会按预期工作。

我推荐三种方法来连接列表,但最推荐的是第一种方法,

# Easiest and least complexity method <= recommended
listone = [1, 2, 3]listtwo = [4, 5, 6]
newlist = listone + listtwoprint(newlist)
# Second-easiest methodnewlist = listone.copy()newlist.extend(listtwo)print(newlist)

在第二种方法中,我将newlist赋值给listone的副本,因为我不想更改listone

# Third methodnewlist = listone.copy()for j in listtwo:newlist.append(j)
print(newlist)

这不是连接列表的好方法,因为我们使用进行循环来连接列表。因此时间复杂度比其他两种方法高得多。

提供的解决方案针对单个列表。如果列表中存在列表并且需要合并相应的列表,则通过进行循环的“+”操作完成工作。

a = [[1,2,3], [4,5,6]]
b = [[0,1,2], [7,8,9]]
for i in range(len(a)):cc.append(a[i] + b[i])

输出:[[1,2,3,0,1,2],[4,5,6,7,8,9]]

用于连接列表的最常见方法是加运算符和内置方法追加,例如:

list = [1,2]
list = list + [3]# list = [1,2,3]
list.append(3)# list = [1,2,3]
list.append([3,4])# list = [1,2,[3,4]]

在大多数情况下,这将起作用,但如果添加了列表,追加函数将不会扩展列表。因为这不是预期的,你可以使用另一个名为延长的方法。它应该适用于结构:

list = [1,2]list.extend([3,4])# list = [1,2,3,4]