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

2024-11-21 08:33:00
admin
原创
6
摘要:问题描述:如何在 Python 中连接两个列表?例子:listone = [1, 2, 3] listtwo = [4, 5, 6] 预期成果:>>> joinedlist [1, 2, 3, 4, 5, 6] 解决方案 1:使用+运算符合并列表:listone = [1, 2, 3] li...

问题描述:

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

例子:

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

预期成果:

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

解决方案 1:

使用+运算符合并列表:

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

joinedlist = listone + listtwo

输出:

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

注意:这将创建一个新列表,其中包含第一个列表中项目的浅表副本,然后是第二个列表中项目的浅表副本。使用copy.deepcopy()获取列表的深层副本。

解决方案 2:

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

值得一提的是,通过接受PEP 448引入了另一种替代方案。

这篇 PEP 题为《附加解包概括》,总体上减少了在 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从内容中创建一个。

解决方案 3:

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

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

解决方案 4:

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

从 3.9 开始,这些是 Python 中连接两个(或更多)列表最流行的 stdlib 方法。

版本限制就地?概括?*
a + b-sum(list_of_lists, [])1
list(chain(a, b))2>=2.3list(chain(*list_of_lists))
[*a, *b]3>=3.5
a += b-是的
a.extend(b)-是的
  • 如果某个解决方案适用于未知数量的列表(例如,在循环或列表推导中),则该解决方案将被视为通用解决方案

脚注

  1. 这是一个巧妙的解决方案,因为它简洁明了。但是sum以成对的方式执行连接,这意味着这是一个二次运算,因为必须为每个步骤分配内存。如果您的列表很大,请不要使用。

  2. chain
    参阅

chain.from_iterable
文档。您首先需要from itertools import chain。串联在内存中是线性的,因此在性能和版本兼容性方面这是最好的。chain.from_iterable是在 2.6 中引入的。

  1. 此方法使用附加解包泛化 (PEP 448),但不能推广到 N 个列表,除非您自己手动解包每个列表。

  2. 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),后者是单个函数调用,更符合惯用语。append由于为列表分配和增长内存的语义,速度较慢。 请参阅此处了解类似的讨论。

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

  • yield从函数中获取列表元素是一种可接受的方法,但是chain效果更快更好(它有一个 C 语言的代码路径,所以速度很快)。

  • operator.add(a, b)是可接受的功能等同于a + b。它的用例主要用于动态方法调度。否则,我认为a + b更喜欢 ,因为它更短,更易读。YMMV。

解决方案 5:

您还可以使用该list.extend()方法将一个添加list到另一个的末尾:

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

listone.extend(listtwo)

如果要保持原始列表完整,可以创建一个新list对象,并将extend两个列表都添加到其中:

mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)

解决方案 6:

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

mergedlist = list(set(listone + listtwo))

解决方案 7:

这很简单,我认为它甚至在教程中已经展示过了:

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

解决方案 8:

这个问题直接询问如何连接两个列表。然而,即使你正在寻找连接多个列表的方法(包括连接零个列表的情况),它的搜索量也相当高。

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

>>> 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, [])

解决方案 9:

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

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

解决方案 10:

值得注意的是,该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']

解决方案 11:

在 Python 3.3+ 中,你可以使用Yield from:

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]

解决方案 12:

对于列表数量较少的情况,您可以简单地将列表加在一起,或者使用就地解包(在 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]

对于列表数量较多的情况,更通用的方法就是使用模块中的chain.from_iterable()1 个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)

解决方案 13:

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

from heapq import merge

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

print list(merge(a, b))

解决方案 14:

如果不能使用加号运算符(+),则可以使用operator导入:

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]

解决方案 15:

如果您需要合并两个具有复杂排序规则的有序列表,则可能必须像下面的代码一样自己进行操作(使用简单的排序规则以提高可读性:-))。

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

解决方案 16:

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

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]

解决方案 17:

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

numpy.concatenate([a,b])

解决方案 18:

使用简单的列表理解:

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

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

解决方案 19:

另一种方法:

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

解决方案 20:

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

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

解决方案 21:

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

上述代码不保留顺序并从每个列表中删除重复项(但不从连接列表中删除重复项)。

解决方案 22:

正如许多人已经指出的那样,如果需要对两个列表应用完全相同的处理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
        [...]

这里要理解的要点是,列表只是可迭代对象的一个​​特例,可迭代对象和其他对象一样;并且for ... inPython 中的循环可以与元组变量一起使用,因此可以简单地同时对多个变量进行循环。

解决方案 23:

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

# 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循环来连接列表。因此时间复杂度比其他两种方法高得多。

解决方案 24:

 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]

解决方案 25:

连接列表最常用的方法是加法运算符和内置方法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]

解决方案 26:

合并列表的一个非常简洁的方法是

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]

解决方案 27:

您也可以只使用sum。

>>> 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]并按预期工作。

解决方案 28:

因此有两种简单的方法。

  1. 使用+:从提供的列表中创建一个新列表

例子:

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
  1. 使用扩展:它将新列表附加到现有列表。这意味着它不会创建单独的列表。

例子:

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是有效的。

解决方案 29:

我假设您想要以下两种方法之一:

保留重复元素

这很简单。只需像字符串一样连接即可:

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

解决方案 30:

提供的解决方案适用于单个列表。如果列表中有列表,并且需要合并相应的列表,则通过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]]

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用