如何在Python中连接两个列表?
示例:
listone = [1, 2, 3]
listtwo = [4, 5, 6]
预期结果:
>>> joinedlist
[1, 2, 3, 4, 5, 6]
如何在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]。 - rickcnagylist3 = listone listone+=listtwo,list3是否也会发生改变? - MikeHPython >= 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系列中的早期版本。在不受支持的版本中,会引发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。
res = [*l1, *reversed(l2)]。因为reversed返回一个迭代器,所以res = l1 + reversed(l2)会抛出一个错误。 - alan** 语法仅支持字符串键。 - user16829600也可以使用itertools.chain()创建一个生成器,它只是简单地遍历两个列表中的项。这允许您将列表(或任何可迭代对象)链接在一起进行处理,而无需将项复制到新列表中:
import itertools
for item in itertools.chain(listone, listtwo):
# Do something with each list item
chain 的速度比较慢(但差距不大),但对于链接多个列表(n >> 2),它是最快的解决方案。 - cs95chain 来创建一个迭代器,遍历所有元素并将结果转换为列表。有时这正是你想要的,但如果你只是想遍历所有元素,那么可以直接使用 chain 的迭代器。这样可能会更快。 - Roel Schroeven截至3.9版本,以下是Python中连接两个(或多个)列表最流行的标准库方法。
| 版本限制 | 原地操作? | 泛化?* | |
|---|---|---|---|
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和chain.from_iterable。您需要首先from itertools import chain。连接在内存中是线性的,因此在性能和版本兼容性方面,这是最好的选择。chain.from_iterable是在2.6中引入的。此方法使用附加解包概括(PEP 448),但除非您自己手动解包每个列表,否则无法推广到N个列表。
a += b和a.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)更冗长,更慢,后者是单个函数调用,更习惯用法。由于列表的内存分配和增长的语义,append更慢。参见 here类似的讨论。
heapq.merge可以工作,但它的用例是在线性时间内合并排序列表。在任何其他情况下使用它都是反模式。
从函数中yield元素列表是一种可接受的方法,但是chain可以更快,更好地执行此操作(它有一个C代码路径,因此很快)。
operator.add(a, b)是a + b的可接受的函数等价物。其主要用途是动态方法分派。否则,建议使用更短、更易读的a + b,这是我的意见。你的经验可能会有所不同。
[i for ls in list_of_lists for i in ls]。如果能把它包含在列表和图表中就太好了。 :) - undefined你还可以使用list.extend()方法来将一个list添加到另一个列表的末尾:
listone = [1,2,3]
listtwo = [4,5,6]
listone.extend(listtwo)
如果您想保留原始列表不变,可以创建一个新的list对象,并将两个列表extend到它上面:mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)
None? - Ayushlistone = [1,2,3]; listtwo = [4,5,6]; listone.extend(listtwo) this returns me None - Ayushlistone 进行原地更新,因此请检查它是否在列表 listone 中。 - Gourneaureturn list1.extend(list2),而这个表达式对我返回了None。 - Ayushmergedlist = list(set(listone + listtwo))
import collections; mergedlist = list(collections.OrderedDict.fromkeys(listone + listtwo))来解决问题。 - SethMMortonmergedlist = list(dict.fromkeys(listone + listtwo))。 - user3064538这很简单,而且我认为甚至在教程中已经展示过了:
>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]
这个问题直接询问如何合并两个列表。然而,即使你正在寻找一种合并许多列表的方法(包括合并零个列表的情况),它在搜索结果中也非常高。
我认为最好的选择是使用列表推导式:
>>> 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()。
更新
评论中Patrick Collins提出的另一种替代方法也可能适合您:sum(a, [])
reduce函数在functools模块中,所以您需要先导入它。 - Dimitris Fasarakis Hilliard+或+=运算符:
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))。 - user3064538itertools.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']
[1,2,5]和[2,4,5,6],您希望重复项被包含在内、排除在外还是不关心? - smci