如何在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]
当前回答
这个问题直接询问加入两个列表。然而,即使您正在寻找一种连接多个列表的方法(包括连接零个列表的情况),它在搜索中也非常高。
我认为最好的选择是使用列表综合:
>>> 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, [])
其他回答
如果您需要使用复杂的排序规则合并两个有序列表,您可能需要像下面的代码一样自行滚动(使用简单的排序规则以提高可读性:-)。
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])
我假设您需要以下两种方法之一:
保留重复元素
这很容易。就像字符串一样连接:
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
正如许多人已经指出的那样,如果需要对两个列表应用完全相同的处理方式,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中的in循环可以与元组变量一起工作,因此同时循环多个变量很简单。
如何在Python中连接两个列表?
截至3.9,这些是在Python中连接两个(或更多)列表的最流行的stdlib方法。
Version Restrictions | In-Place? | Generalize to N lists? | |
---|---|---|---|
a+b |
- | No | sum([a, b, c], []) 1 |
list(chain(a,b)) 2 |
>=2.3 | No | list(chain(a, b, c)) |
[*a, *b] 3 |
>=3.5 | No | [*a, *b, *c] |
a += b |
- | Yes | No |
a.extend(b) |
- | Yes | No |
脚注这是一个巧妙的解决方案,因为它简洁。但sum以成对的方式执行连接,这意味着这是一个必须为每个步骤分配作为存储器的二次运算。做如果您的列表很大,请不要使用。参见链条和链接from_iteable从文档中。您需要首先从itertools导入链。级联在内存中是线性的,因此在性能和版本兼容性。chain.from_iteable在2.6中引入。此方法使用附加解包泛化(PEP 448),但不能归纳为N个列表,除非您自己手动打开每个列表。a+=b和a.extend(b)在所有实际用途中或多或少是等效的。+=当在列表中调用时,将在内部调用列表__iadd_,它将第一个列表扩展第二个列表。
表演
2-列表连接1
这些方法之间没有太大区别,但这是有意义的,因为它们都具有相同的复杂性(线性)。除了风格上的问题外,没有特别的理由更喜欢一个而不是另一个。
N-列表连接
已使用perfplot模块生成绘图。代码,供您参考。
1.iadd(+=)和extend方法在适当的地方运行,因此每次测试前都必须生成一个副本。为了保持公平,所有方法都有左侧列表的预复制步骤,可以忽略。
对其他解决方案的评论
不要使用DUNDER方法列表__以任何方式、形状或形式直接添加__。事实上,请不要使用dunder方法,并像设计的那样使用运算符和运算符函数。Python有精心设计的语义,这些语义比直接调用dunder更复杂。这里有一个例子。综上所述,a.__add__(b)=>BAD;a+b=>良好。这里的一些答案为成对串联提供了reduce(operator.add,[a,b])——这与sum([a,b],[])相同,只是更加冗长。任何使用set的方法都会删除重复项并丢失排序。小心使用。对于b中的i:a.append(i)比a.extend(b)更冗长,也更慢,后者是单函数调用,更惯用。由于为列表分配和增长内存的语义,append速度较慢。有关类似的讨论,请参见此处。heapq.mmerge可以工作,但它的用例是在线性时间内合并排序列表。在任何其他情况下使用它都是一种反模式。从函数中生成列表元素是一种可以接受的方法,但chain可以更快更好地实现这一点(它有一个C语言的代码路径,所以速度很快)。operator.add(a,b)是一个可接受的等价于a+b的函数。它的用例主要用于动态方法调度。否则,在我看来,更喜欢a+b,它更简短,更易读。YMMV。
如果不能使用加号运算符(+),则可以使用运算符导入:
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]