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

y2k*_*y2k 2250 python list concatenation

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

例:

listone = [1, 2, 3]
listtwo = [4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

预期结果:

>>> joinedlist
[1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

Dan*_*l G 3539

您可以使用+运算符来组合它们:

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

joinedlist = listone + listtwo
Run Code Online (Sandbox Code Playgroud)

输出:

>>> joinedlist
[1,2,3,4,5,6]
Run Code Online (Sandbox Code Playgroud)

  • 另一个有用的细节:`listone + = listtwo`导致`listone == [1,2,3,4,5,6] (204认同)
  • @Daniel它将创建一个新列表,其中包含第一个列表中项目的浅表副本,然后是第二个列表中项目的浅表副本.使用copy.deepcopy获取列表的深层副本. (140认同)
  • 这会创建listone的深层副本并附加listtwo吗? (95认同)
  • @ br1ckb0t会改变listone指向的内容吗?所以:`list3 = listone``listone + = listtwo` list3也改变了吗? (16认同)
  • 它确实改变了list3.但是,如果这不是问题,那么添加两个列表而不是创建新列表会更简单. (11认同)
  • @rickcnagy `listone += listtwo` 应该避免。应该使用“list.extend()”。`listone.extend(listtwo)` (4认同)
  • 警告:我不知道这是否是 Python3 的细节,但在某些情况下(numpy 数组)[1,2,3]+[4] 给出 [5,6,7]!!! (3认同)
  • @MikeH是的,它会更改list3。 (2认同)
  • @Pygmalion不是特定于Python3,而是特定于NumPy数组如何处理运算符。有关串联NumPy数组的信息,请参见Robert Rossney的答案中的JF Sebastian的答案。 (2认同)

Rob*_*ney 282

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

import itertools
for item in itertools.chain(listone, listtwo):
    # Do something with each list item
Run Code Online (Sandbox Code Playgroud)

  • 这是更好的方法,因为它也适用于numpy数组. (26认同)
  • @ d.putto:numpy数组的单项访问速度非常慢(每次访问需要将原始内存转换为C类型到Python对象.矢量化操作,如`np.dot()`直接在C类型上工作而不需要往返Python,因此很快).您可以使用`merged = np.r_ [a,b]`来获取连接的numpy数组. (13认同)
  • 对于两个列表,`chain` 处于较慢的一侧(但不是很多),但是对于链接多个列表(n >> 2)来说是最快的解决方案。 (9认同)
  • 将以相同的方式工作:mergedList中的项目的mergedList = itertools.chain(listone,listtwo): (2认同)

Jim*_*ard 201

Python >= 3.5替代方案:[*l1, *l2]

尽管这是一个古老的答案,但通过接受PEP 448值得一提的方法引入了另一种替代方案.

标题为Additional Unpacking Generalizations的PEP *在Python中使用starred 表达式时通常会减少一些语法限制; 有了它,加入两个列表(适用于任何可迭代的)现在也可以用:

>>> 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]
Run Code Online (Sandbox Code Playgroud)

此功能是为Python定义的,3.5它尚未被移植到该3.x系列中的先前版本.在不受支持的版本中SyntaxError,将引发a.

与其他方法一样,这也创建了相应列表中元素的浅层副本.


这种方法的好处是你真的不需要列表来执行它,任何可迭代的东西都可以.如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
Run Code Online (Sandbox Code Playgroud)

以下不会:

res = [*l, *r]
Run Code Online (Sandbox Code Playgroud)

因为它将首先解压缩迭代的内容,然后简单地list从内容中创建一个.

  • 处理可迭代类型的解包方法的一个很好的例子是在您连接的列表之一上返回迭代器的函数。例如,您可以反转要连接的列表之一:`res = [*l1, *reversed(l2)]`。由于 `reversed` 返回一个迭代器,`res = l1 + reversed(l2)` 会抛出一个错误。 (9认同)
  • 我的语法问题必须指出:*字典 (8认同)
  • 值得注意的是,这类似于在 python 中组合字典。dict3 = {**dict1, **dict2}。请注意,我们使用 ** 来解包字典,而对于列表,我们使用 * 来解包。 (4认同)
  • 很有意思。您知道这种方法与加法相比的性能如何吗? (3认同)

Rad*_*ast 199

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

mergedlist = list(set(listone + listtwo))
Run Code Online (Sandbox Code Playgroud)

  • 但是,如果这是您感兴趣的话,它也会删除重复项.列表添加不会那样做. (42认同)
  • 如果x不在listone中,那么比``listone + [x for x in listtwo]更好`` (10认同)
  • +1恕我直言这是"合并"(联合)列表的正确方法,而"已批准"答案描述了如何组合/添加列表(multiset) (8认同)
  • 有什么方法可以做到这一点并保留订购信息? (2认同)
  • 如果您关心维护输入顺序,那么`import collections; mergedlist = list(collections.OrderedDict.fromkeys(listone + listtwo))将解决问题。 (2认同)

Gou*_*eau 157

您还可以使用extend以添加list另一个的结尾添加:

listone = [1,2,3]
listtwo = [4,5,6]
mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
Run Code Online (Sandbox Code Playgroud)

  • @SergeyIvanov不,不会.`list.extend`不会去任何地方. (35认同)
  • 它对“listone”进行了就地更新。所以检查它是否在列表 `listone` 中 (8认同)
  • @Ayush,extend 方法使用 listtwo 中的值更新 listone 并返回 None 。您想要执行的操作:listone.extend(listtwo),然后返回listone (3认同)
  • 为什么在我的例子中这个方法返回“None”? (2认同)

Tuu*_*lli 72

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

>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

  • 当listone和listtwo具有不同数量的元素时,这也适用;-) (2认同)
  • @albus_c为什么您不希望它呢? (2认同)

won*_*ice 49

这个问题直接询问加入两个列表.然而,即使您正在寻找加入许多列表的方式(包括加入零列表时的情况),它在搜索中也相当高.

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

>>> 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]
Run Code Online (Sandbox Code Playgroud)

您也可以创建生成器:

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

老答案

考虑这种更通用的方法:

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

将输出:

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

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

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

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

如果你不需要a list,但只是一个可迭代的,省略list().

更新

帕特里克柯林斯在评论中提出的替代方案也适用于您:

sum(a, [])
Run Code Online (Sandbox Code Playgroud)

  • `sum(a,[])`仅在"a"是列表列表时有效. (3认同)
  • Python 3注意:`reduce`现在位于`functools`中,因此您需要先导入它. (3认同)
  • @Procyclinsur并且列表的列表包含整数 (2认同)

Amy*_*yth 40

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

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

c = a + b
Run Code Online (Sandbox Code Playgroud)

要么:

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

c += (a + b)
Run Code Online (Sandbox Code Playgroud)

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

c = list(set(a + b))
Run Code Online (Sandbox Code Playgroud)

  • 最后一部分可以任意重新排序项目。如果你想保留顺序,在 CPython 3.6+ 上你可以执行 `list(dict.fromkeys(a + b))` (2认同)

cs9*_*s95 38

如何在Python中串联两个列表?

从3.7开始,这些是在python中串联两个(或多个)列表的最受欢迎的stdlib方法。

在此处输入图片说明

脚注

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

  2. 查看chain 和阅读 chain.from_iterable 文档。您需要import itertools先。串联在内存中是线性的,因此这在性能和版本兼容性方面是最佳的。chain.from_iterable已在2.6中引入。

  3. 此方法使用“ 其他解包概述”(PEP 448),但是除非您手动手动解压缩每个列表,否则无法将其归纳为N个列表。

  4. a += ba.extend(b)在所有实际用途上大致相同。+=当在列表上调用时list.__iadd__,将内部调用 ,从而将第一个列表扩展到第二个列表。


性能

2列表串联1

在此处输入图片说明

N列表串联

在此处输入图片说明

使用perfplot模块已生成图。代码,供您参考。

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


对其他解决方案的评论

  • 请勿list.__add__以任何方式,形状或形式直接使用DUNDER方法。实际上,请避免使用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)单一功能调用和惯用语言更加罗word,并且速度更慢。append之所以变慢,是因为为列表分配和增长了内存的语义。参见此处进行类似的讨论。

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

  • yield从函数中列出列表元素是一种可以接受的方法,但是chain这样做更快,更好(它在C中具有代码路径,因此速度很快)。

  • operator.add(a, b)是可以接受的等效功能a + b。它的用例主要用于动态方法分派。否则,在我看来,最好选择更a + b短,更易读的格式。YMMV。

  • @ganeshdeshmukh TL;DR 是它们都很好,你选择哪一个主要是风格问题。“这些方法之间没有太大区别,但考虑到它们都具有相同的复杂性(线性),这是有道理的。除了风格问题之外,没有特别的理由更喜欢其中一种方法。”我的解决方案中未列出解决方案回答,或者在“评论”中批评我建议不要使用。 (3认同)
  • 那么哪种方法是性能方面最好、更快的方法呢?请告诉。 (2认同)

Dar*_*zak 26

值得注意的是,该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']
Run Code Online (Sandbox Code Playgroud)

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

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


小智 21

使用Python 3.3+,您可以使用以下产量:

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

def merge(l1, l2):
    yield from l1
    yield from l2

>>> list(merge(listone, listtwo))
[1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

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

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]
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用 [`itertools.chain`](https://docs.python.org/library/itertools.html#itertools.chain) (等效)而不是定义自己的函数。 (2认同)

lav*_*ngh 18

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

from heapq import merge

a = [1, 2, 4]
b = [2, 4, 6, 7]

print list(merge(a, b))
Run Code Online (Sandbox Code Playgroud)

  • 注意,这假定`a`和`b`已经排序 (6认同)

jpi*_*ihl 15

如果你不能使用plus运算符(+),你可以使用这个 operator函数:

import operator

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

result = operator.add(listone, listtwo)
print(result)

>>> [1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

或者,如果你不喜欢使用dunders,你可以使用__add__导入:

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

result = list.__add__(listone, listtwo)
print(result)

>>> [1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

有人可能会说这有点可读性.

  • 抢劫邓迪通常不是最好的方法。如果“ +”不在桌面上,请使用“ operator.add”。 (3认同)
  • 为什么 plus 运算符不可用? (2认同)
  • 通常不会:),但是如果您要使用map函数进行列表串联,或者要将add函数存储在变量中,则不能使用+。 (2认同)

Kas*_*mvd 13

作为更多列表的更通用方法,您可以将它们放在列表中并使用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]
Run Code Online (Sandbox Code Playgroud)

1.注意chain.from_iterable()在python => 2.6中可用.在其他版本中使用chain(*l)


Jam*_*eug 12

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

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))
Run Code Online (Sandbox Code Playgroud)

输出

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]
Run Code Online (Sandbox Code Playgroud)


Mr *_*ark 10

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

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])
Run Code Online (Sandbox Code Playgroud)


小智 9

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

numpy.concatenate([a,b])
Run Code Online (Sandbox Code Playgroud)

  • 这个问题不要求numpy。 (9认同)

min*_*iao 7

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

mergedlist =[]
for elem in listone:
    mergedlist.append(elem)
for elem in listtwo:
    mergedlist.append(elem)
Run Code Online (Sandbox Code Playgroud)

  • 只是你知道,如果这是你在实践中所做的事情,这比其他提议的方法慢得多.见http://stackoverflow.com/questions/17479361/iterating-vs-list-concatenation/17479468#17479468 (8认同)

Sup*_*ova 7

list(set(listone) | set(listtwo))
Run Code Online (Sandbox Code Playgroud)

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


Cry*_*ore 7

 a = [1, 2, 3]
 b = [4, 5, 6]
     
 c = a + b
 print(c)
Run Code Online (Sandbox Code Playgroud)

输出

 a = [1, 2, 3]
 b = [4, 5, 6]
     
 c = a + b
 print(c)
Run Code Online (Sandbox Code Playgroud)

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

另一种解决方案

 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)
Run Code Online (Sandbox Code Playgroud)

输出

>>> [1, 2, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)


Fra*_*asi 6

正如许多人已经指出itertools.chain()的那样,如果需要对两个列表都应用完全相同的处理方式,那就是要走的路.在我的情况下,我有一个标签和一个标志,从一个列表到另一个列表不同,所以我需要一些稍微复杂的东西.事实证明,幕后itertools.chain()只需执行以下操作:

for it in iterables:
    for element in it:
        yield element
Run Code Online (Sandbox Code Playgroud)

(请参阅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
        [...]
Run Code Online (Sandbox Code Playgroud)

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


小智 6

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

# Easiest and least complexity method <= recommended

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

newlist = listone + listtwo
print(newlist)

# Second-easiest method
newlist = listone.copy()
newlist.extend(listtwo)
print(newlist)
Run Code Online (Sandbox Code Playgroud)

在第二种方法中,我分配newlist给 的副本listone,因为我不想更改listone.

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

print(newlist)
Run Code Online (Sandbox Code Playgroud)

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


小智 6

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

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]]
Run Code Online (Sandbox Code Playgroud)

对于大多数情况,这都是可行的,但如果添加了列表,追加函数将不会扩展列表。因为这不是预期的,所以您可以使用另一种名为“extend”的方法。它应该与结构一起使用:

list = [1,2]
list.extend([3,4])
# list = [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)


Aka*_*ngh 5

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

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

这给了我们

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


z33*_*33k 5

使用简单的列表理解:

joined_list = [item for list_ in [list_one, list_two] for item in list_]
Run Code Online (Sandbox Code Playgroud)

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


sur*_*rya 5

其它的办法:

>>> listone = [1, 2, 3]
>>> listtwo = [4, 5, 6]
>>> joinedlist = [*listone, *listtwo]
>>> joinedlist
[1, 2, 3, 4, 5, 6]
>>> 
Run Code Online (Sandbox Code Playgroud)

  • [*a, *b] 如何改进 a + b? (3认同)