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

y2k 2250 python list concatenation

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

例:

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

预期结果:

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

Daniel G.. 3539

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

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

joinedlist = listone + listtwo

输出:

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

  • 另一个有用的细节:`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认同)
  • @MikeH是的,它会更改list3。 (2认同)
  • @Pygmalion不是特定于Python3,而是特定于NumPy数组如何处理运算符。有关串联NumPy数组的信息,请参见Robert Rossney的答案中的JF Sebastian的答案。 (2认同)

Robert Rossn.. 282

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

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

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

Jim Fasaraki.. 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]

此功能是为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

以下不会:

res = [*l, *r]

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


Radagast.. 199

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

mergedlist = list(set(listone + listtwo))

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

Gourneau.. 157

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

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

  • @SergeyIvanov不,不会.`list.extend`不会去任何地方. (35认同)

Tuure Laurin.. 72

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

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

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

wonder.mice.. 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]

您也可以创建生成器:

>>> 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))

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

更新

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

sum(a, [])

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

Amyth.. 40

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

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))


cs95.. 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。


Dariusz Walc.. 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']

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

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


小智.. 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]

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

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]


lavee_singh.. 18

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

from heapq import merge

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

print list(merge(a, b))

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

jpihl.. 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]

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

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

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

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

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

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

Kasramvd.. 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]

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


Mr Shark.. 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])


mingxiao.. 7

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

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

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

SuperNova.. 7

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

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


Francesco Ma.. 6

正如许多人已经指出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
        [...]

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


z33k.. 5

使用简单的列表理解:

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

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


归档时间:

查看次数:

2199794 次

最近记录:

7 月,2 周 前