提问人:y2k 提问时间:11/12/2009 最后编辑:Peter Mortenseny2k 更新时间:4/20/2023 访问量:4324831
如何在 Python 中连接两个列表?
How do I concatenate two lists in Python?
问:
如何在 Python 中连接两个列表?
例:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
预期成果:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
答:
使用运算符组合列表:+
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]
list3 = listone
listone+=listtwo
这很简单,我认为它甚至在教程中已经显示过:
>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]
也可以创建一个生成器,该生成器使用 itertools.chain()
简单地遍历两个列表中的项目。这允许您将列表(或任何可迭代对象)链接在一起进行处理,而无需将项目复制到新列表:
import itertools
for item in itertools.chain(listone, listtwo):
# Do something with each list item
评论
chain
对于两个列表来说,速度较慢(但不是很多),但对于链接多个列表(n >> 2)来说,它是最快的解决方案。
chain
chain
您可以使用集来获取唯一值的合并列表
mergedlist = list(set(listone + listtwo))
评论
listone + [x for x in listtwo if x not in listone]
import collections; mergedlist = list(collections.OrderedDict.fromkeys(listone + listtwo))
您也可以使用 list.extend()
方法将 a 添加到另一个方法的末尾:list
listone = [1,2,3]
listtwo = [4,5,6]
listone.extend(listtwo)
如果要保持原始列表不变,可以创建一个新对象,并创建两个列表:list
extend
mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
评论
None
listone = [1,2,3]; listtwo = [4,5,6]; listone.extend(listtwo)
这又回到了我身上None
listone
listone
return list1.extend(list2)
None
值得注意的是,该函数接受可变数量的参数: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']
您可以简单地使用 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))
评论
list(dict.fromkeys(a + b))
您可以使用在对象上定义的方法:append()
list
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])
评论
heapq.merge
。
在 Python 3.3+ 中,您可以使用以下方面的 yield:
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]
评论
itertools.chain
(等效)来定义自己的函数。
如果不能使用加号运算符 (),则可以使用 import:+
operator
import operator
listone = [1,2,3]
listtwo = [4,5,6]
result = operator.add(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
或者,您也可以使用 dunder 函数:__add__
listone = [1,2,3]
listtwo = [4,5,6]
result = list.__add__(listone, listtwo)
print(result)
>>> [1, 2, 3, 4, 5, 6]
评论
+
operator.add
对于列表数量较少的情况,您可以简单地将列表添加在一起或使用就地解包(在 Python-3.5+ 中可用):
In [1]: listone = [1, 2, 3]
...: listtwo = [4, 5, 6]
In [2]: listone + listtwo
Out[2]: [1, 2, 3, 4, 5, 6]
In [3]: [*listone, *listtwo]
Out[3]: [1, 2, 3, 4, 5, 6]
对于列表数量较多的情况,作为更通用的方法,您可以使用模块中的 1 个函数。此外,基于这个答案,这个函数是最好的;或者至少是扁平化嵌套列表的一个非常好的方法。chain.from_iterable()
itertools
>>> 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)'。
如果要以排序形式合并两个列表,可以使用库中的函数。merge
heapq
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, [])
评论
reduce
functools
正如许多人已经指出的那样,如果需要对两个列表应用完全相同的处理方式,那么这是要走的路。就我而言,我有一个标签和一个标志,它们从一个列表到另一个列表都不同,所以我需要稍微复杂一些的东西。事实证明,幕后只是做了以下事情: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 的标题为 Additional Unpacking Generalizations,在 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 系列中的先前版本。在不受支持的版本中,将引发 a。SyntaxError
与其他方法一样,这也创建了相应列表中元素的浅拷贝。
这种方法的好处是,你真的不需要列表来执行它;任何可迭代的东西都可以。如PEP所述:
这也是一种更具可读性的方法,可以将可迭代对象求和 列表,例如现在 等同于 just .
my_list + list(my_tuple) + list(my_range)
[*my_list, *my_tuple, *my_range]
因此,虽然添加 with 会由于类型不匹配而引发:+
TypeError
l = [1, 2, 3]
r = range(4, 7)
res = l + r
以下不会:
res = [*l, *r]
因为它将首先解压缩可迭代对象的内容,然后简单地从内容中创建一个。list
评论
res = [*l1, *reversed(l2)]
reversed
res = l1 + reversed(l2)
**
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]
评论
list.__add__
operator.add
sum(list_of_lists, [])
obj.__class__
obj.__dict__
__add__
np.union1d
使用简单的列表推导式:
joined_list = [item for list_ in [list_one, list_two] for item in list_]
它具有使用附加解包泛化的最新方法的所有优点 - 即您可以以这种方式连接任意数量的不同可迭代对象(例如,列表、元组、范围和生成器) - 并且不限于 Python 3.5 或更高版本。
如果您使用的是 NumPy,则可以使用以下命令连接两个兼容维度的数组:
numpy.concatenate([a,b])
评论
所以有两种简单的方法。
- 使用
+
:它从提供的列表创建一个新列表
例:
In [1]: a = [1, 2, 3]
In [2]: b = [4, 5, 6]
In [3]: a + b
Out[3]: [1, 2, 3, 4, 5, 6]
In [4]: %timeit a + b
10000000 loops, best of 3: 126 ns per loop
- 使用扩展:它将新列表附加到现有列表。这意味着它不会创建单独的列表。
例:
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 方法。
版本限制 | 就地? | 概括?* | |
---|---|---|---|
a + b |
- | 不 | sum(list_of_lists, []) 1 |
list(chain(a, b)) 2 |
>=2.3 | 不 | list(chain(*list_of_lists)) |
[*a, *b] 3 |
>=3.5 | 不 | 不 |
a += b |
- | 是的 | 不 |
a.extend(b) |
- | 是的 | 不 |
* 如果一个解决方案适用于未知数量的列表(例如,在循环或列表推导中),则该解决方案将有资格成为广义解决方案
脚注
这是一个巧妙的解决方案,因为它简洁明了。但以成对方式执行串联,这意味着这是一个 二次运算,因为必须为每个步骤分配内存。做 如果您的列表很大,则不要使用。
sum
请参阅文档中的
链
和chain.from_iterable
。您需要先。 串联在内存中是线性的,因此这在以下方面是最好的 性能和版本兼容性。 在 2.6 中引入。from itertools import chain
chain.from_iterable
此方法使用附加解包概化 (PEP 448),但不能 推广到 N 个列表,除非您自己手动解压缩每个列表。
a += b
并且对于所有实际目的或多或少是等效的。 当对列表调用时,将在内部调用 ,这将第一个列表扩展第二个列表。a.extend(b)
+=
list.__iadd__
性能
2-列表串联1
这些方法之间没有太大区别,但这是有道理的,因为它们都具有相同的复杂度顺序(线性)。除了风格问题之外,没有特别的理由偏爱一个而不是另一个。
N 列表串联
1. iadd
(+=
) 和 extend
方法就地运行,因此每次测试前都必须生成一个副本。为了公平起见,所有方法都有一个可以忽略的左侧列表的预复制步骤。
对其他解决方案的评论
请勿以任何方式、形状或形式直接使用 DUNDER 方法。事实上,要远离 dunder 方法,并使用它们设计的运算符和函数。Python 在这些语义中加入了谨慎的语义,这比直接调用 dunder 要复杂得多。下面是一个示例。所以,总而言之,=> BAD; => 好。
list.__add__
operator
a.__add__(b)
a + b
这里的一些答案提供了成对串联 - 这与更冗长的相同。
reduce(operator.add, [a, b])
sum([a, b], [])
使用的任何方法都会删除重复项并丢失排序。请谨慎使用。
set
for i in b: a.append(i)
比 更啰嗦,速度更慢,是单函数调用,更惯用。 由于为列表分配和增长内存的语义,因此速度较慢。有关类似的讨论,请参阅此处。a.extend(b)
append
heapq.merge
将起作用,但它的用例是用于在线性时间内合并排序列表。在任何其他情况下使用它都是一种反模式。yield
从函数中列出元素是一种可接受的方法,但这样做更快更好(它在 C 中有一个代码路径,所以它很快)。chain
operator.add(a, b)
是可接受的等效函数。它的用例主要用于动态方法调度。否则,在我看来,更喜欢更短、更易读的。YMMV。a + b
a + b
评论
"There's not much difference between these methods but that makes sense given they all have the same order of complexity (linear). There's no particular reason to prefer one over the other except as a matter of style.
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print(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+l2
return 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 list
l3.append(j)
return l3
您可以在 Python 中使用 union() 函数。
joinedlist = union(listone, listtwo)
print(joinedlist)
从本质上讲,它是删除两个列表中的每个重复项之一。由于您的列表没有任何重复项,因此它只返回两个列表的串联版本。
评论
union
不适用于列表,您可以将其与 sets 或 dict 一起使用
另一种方式:
>>> 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 + listtwo
print(newlist)
# Second-easiest method
newlist = listone.copy()
newlist.extend(listtwo)
print(newlist)
在第二种方法中,我分配给 的副本,因为我不想更改 。newlist
listone
listone
# Third method
newlist = listone.copy()
for j in listtwo:
newlist.append(j)
print(newlist)
这不是连接列表的好方法,因为我们使用 for 循环来连接列表。因此,时间复杂度远高于其他两种方法。
提供的解决方案适用于单个列表。如果列表中有列表并且需要合并相应的列表,则通过 for 循环的“+”操作可以完成工作。
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]]
用于连接列表的最常用方法是加号运算符和内置方法 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]]
在大多数情况下,这将起作用,但如果添加了列表,append 函数将不会扩展列表。由于这不是预期的,因此可以使用另一种名为 extend 的方法。它应该适用于以下结构:
list = [1,2]
list.extend([3,4])
# list = [1,2,3,4]
上一个:删除列表中的重复项
下一个:如何检查列表是否为空?
评论
[1,2,5] and [2,4,5,6]