逐元素添加两个列表?

2024-12-18 08:38:00
admin
原创
176
摘要:问题描述:我现在有:list1 = [1, 2, 3] list2 = [4, 5, 6] 我希望拥有:[1, 2, 3] + + + [4, 5, 6] || || || [5, 7, 9] 只需将两个列表逐个元素相加即可。我当然可以迭代这两个列表,但我不想这样做。最符合 Python 风格的方式是什...

问题描述:

我现在有:

list1 = [1, 2, 3]
list2 = [4, 5, 6]

我希望拥有:

[1, 2, 3]
 +  +  +
[4, 5, 6]
|| || ||
[5, 7, 9]

只需将两个列表逐个元素相加即可。

我当然可以迭代这两个列表,但我不想这样做。

最符合 Python 风格的方式是什么?


解决方案 1:

使用:mapoperator.add

>>> from operator import add
>>> list( map(add, list1, list2) )
[5, 7, 9]

或者zip使用列表推导:

>>> [sum(x) for x in zip(list1, list2)]
[5, 7, 9]

时间比较:

>>> list2 = [4, 5, 6]*10**5
>>> list1 = [1, 2, 3]*10**5
>>> %timeit from operator import add;map(add, list1, list2)
10 loops, best of 3: 44.6 ms per loop
>>> %timeit from itertools import izip; [a + b for a, b in izip(list1, list2)]
10 loops, best of 3: 71 ms per loop
>>> %timeit [a + b for a, b in zip(list1, list2)]
10 loops, best of 3: 112 ms per loop
>>> %timeit from itertools import izip;[sum(x) for x in izip(list1, list2)]
1 loops, best of 3: 139 ms per loop
>>> %timeit [sum(x) for x in zip(list1, list2)]
1 loops, best of 3: 177 ms per loop

解决方案 2:

其他人给出了如何在纯 Python 中执行此操作的示例。如果要对包含 100,000 个元素的数组执行此操作,则应使用 numpy:

In [1]: import numpy as np
In [2]: vector1 = np.array([1, 2, 3])
In [3]: vector2 = np.array([4, 5, 6])

现在,逐元素加法非常简单

In [4]: sum_vector = vector1 + vector2
In [5]: print sum_vector
[5 7 9]

就像在 Matlab 中一样。

与 Ashwini 最快版本进行比较的时间:

In [16]: from operator import add
In [17]: n = 10**5
In [18]: vector2 = np.tile([4,5,6], n)
In [19]: vector1 = np.tile([1,2,3], n)
In [20]: list1 = [1,2,3]*n
In [21]: list2 = [4,5,6]*n
In [22]: timeit map(add, list1, list2)
10 loops, best of 3: 26.9 ms per loop

In [23]: timeit vector1 + vector2
1000 loops, best of 3: 1.06 ms per loop

所以这是快了 25 倍!但要使用适合您情况的方法。对于一个简单的程序,您可能不想安装 numpy,因此请使用标准 python(我发现Henry 的版本是最 Pythonic 的版本)。如果您喜欢严肃的数字运算,那就让我们numpy来做繁重的工作吧。对于速度狂人来说:似乎从 开始 numpy 解决方案更快n = 8

解决方案 3:

[a + b for a, b in zip(list1, list2)]

解决方案 4:

正如其他人所描述的,一种快速且节省空间的解决方案是使用具有内置矢量操作功能的 numpy (np):

1.使用 Numpy

x = np.array([1,2,3])
y = np.array([2,3,4])
print x+y

2. 内置功能

2.1 Lambda

list1=[1, 2, 3]
list2=[4, 5, 6]
print map(lambda x,y:x+y, list1, list2)

请注意,map() 支持多个参数。

2.2 zip 和列表推导

list1=[1, 2, 3]
list2=[4, 5, 6]
print [x + y for x, y in zip(list1, list2)]

解决方案 5:

从我的观点来看,它使用起来更简单numpy

import numpy as np
list1=[1,2,3]
list2=[4,5,6]
np.add(list1,list2)

结果:

终端执行

有关详细参数信息,请查看此处:numpy.add

解决方案 6:

如果您有未知数量的列表,并且不需要导入任何内容,那么这也许是 Python 风格的并且稍微有用。

只要列表长度相同,您就可以使用以下函数。

这里 *args 接受可变数量的列表参数(但每个参数的数量仅相加相同)。

在返回的列表中再次使用 * 来解包每个列表中的元素。

def sum_lists(*args):
    return list(map(sum, zip(*args)))

a = [1,2,3]
b = [1,2,3]  

sum_lists(a,b)

输出:

[2, 4, 6]

或者有 3 个列表

sum_lists([5,5,5,5,5], [10,10,10,10,10], [4,4,4,4,4])

输出:

[19, 19, 19, 19, 19]

解决方案 7:

也许“最符合 Python 风格的方法”应该包括处理 list1 和 list2 大小不同的情况。应用其中一些方法会悄悄地给你一个答案。numpy 方法会让你知道,最有可能的是 ValueError。

例子:

import numpy as np
>>> list1 = [ 1, 2 ]
>>> list2 = [ 1, 2, 3]
>>> list3 = [ 1 ]
>>> [a + b for a, b in zip(list1, list2)]
[2, 4]
>>> [a + b for a, b in zip(list1, list3)]
[2]
>>> a = np.array (list1)
>>> b = np.array (list2)
>>> a+b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (2) (3)

如果这是你问题中的一个函数,你可能想要什么结果?

解决方案 8:

如果您需要处理不同大小的列表,请不要担心!出色的itertools模块可以满足您的需求:

>>> from itertools import zip_longest
>>> list1 = [1,2,1]
>>> list2 = [2,1,2,3]
>>> [sum(x) for x in zip_longest(list1, list2, fillvalue=0)]
[3, 3, 3, 3]
>>>

在 Python 2 中,zip_longest被称为izip_longest

另请参阅此相关答案并评论另一个问题。

解决方案 9:

这很简单numpy.add()

import numpy

list1 = numpy.array([1, 2, 3])
list2 = numpy.array([4, 5, 6])
result = numpy.add(list1, list2) # result receive element-wise addition of list1 and list2
print(result)
array([5, 7, 9])

请参阅此处的文档

如果你想接收一个python列表:

result.tolist()

解决方案 10:

这将适用于 2 个或更多列表;遍历列表列表,但使用 numpy 加法来处理每个列表的元素

import numpy as np
list1=[1, 2, 3]
list2=[4, 5, 6]

lists = [list1, list2]
list_sum = np.zeros(len(list1))
for i in lists:
   list_sum += i
list_sum = list_sum.tolist()    

[5.0, 7.0, 9.0]

解决方案 11:

[list1[i] + list2[i] for i in range(len(list1))]

解决方案 12:

将 map 与 lambda 函数结合使用:

>>> map(lambda x, y: x + y, list1, list2)
[5, 7, 9]

解决方案 13:

我没有计时,但我猜测这会很快:

import numpy as np
list1=[1, 2, 3]
list2=[4, 5, 6]

list_sum = (np.add(list1, list2)).tolist()

[5, 7, 9]

解决方案 14:

  • zip 函数在这里很有用,与列表推导一起使用v1v2

  • 如果您有一个列表列表(而不是仅仅两个列表),则可以使用v3

  • 对于长度不同的列表(例如:通过在第一个/第二个列表的末尾添加 1),那么您可以尝试这样的操作(使用 zip_longest)-v4

first = [1, 2, 3, 1]
second = [4, 5, 6]

output: [5, 7, 9, 1]
  • 如果有未知数量的相同长度的列表,则可以使用函数v5

  • v6- operator 模块导出一组与 Python 固有运算符相对应的高效函数。例如,operator.add(x, y)相当于表达式x+y

  • v7- 假设两个列表的长度first相同second,则不需要 zip 或其他任何东西。

first = [1, 2, 3]
second = [4, 5, 6]


# v1: Using list comprehension and sum function
# Simply an element-wise addition of two lists.
# Pythonic approach leveraging list comprehension and sum function.
third1 = [sum(i) for i in zip(first, second)]

# v2: Using list comprehension and element-wise addition
# Simply an element-wise addition of two lists.
# Pythonic approach using list comprehension with element-wise addition.
third2 = [x + y for x, y in zip(first, second)]

# v3: Using list comprehension and sum function with unpacking
# Simply an element-wise addition of two lists.
# Pythonic approach utilizing list comprehension, sum function, and unpacking.
lists_of_lists = [[1, 2, 3], [4, 5, 6]]
third3 = [sum(x) for x in zip(*lists_of_lists)]

# v4: Using map, zip_longest, and sum function
# Simply an element-wise addition of two lists.
# Pythonic approach using map, zip_longest for equal-length iteration, and sum function.
from itertools import zip_longest
third4 = list(map(sum, zip_longest(first, second, fillvalue=0)))

# v5: Using a custom function and zip with *args
# Simply an element-wise addition of two lists.
# Pythonic approach with a custom function using zip and *args for flexibility.
def sum_lists(*args):
    return list(map(sum, zip(*args)))
third5 = sum_lists(first, second)

# v6: Using map, operator.add, and element-wise addition
# Simply an element-wise addition of two lists.
# Pythonic approach leveraging map, operator.add for element-wise addition.
import operator
third6 = list(map(operator.add, first, second))

# v7: Using list comprehension and range-based indexing
# Simply an element-wise addition of two lists.
# Pythonic approach using list comprehension with range-based indexing.
third7 = [first[i] + second[i] for i in range(len(first))]


print(third1) # [5, 7, 9]
print(third2) # [5, 7, 9]
print(third3) # [5, 7, 9]
print(third4) # [5, 7, 9]
print(third5) # [5, 7, 9]
print(third6) # [5, 7, 9]
print(third7) # [5, 7, 9]

解决方案 15:

尽管实际问题并不想遍历列表来生成结果,但所有提出的解决方案实际上都是这样做的!

回顾一下:如果不考虑所有向量元素,就无法将两个向量相加。因此,大多数此类解决方案的算法复杂度都是 Big-O(n)。其中 n 是向量的维数。

因此,从算法的角度来看,使用 for 循环迭代生成结果列表是合乎逻辑且符合 Python 规范的。此外,此方法没有调用或导入任何额外库的开销。

# Assumption: The lists are of equal length.
resultList = [list1[i] + list2[i] for i in range(len(list1))]

这里展示/讨论的时间取决于系统和实现,不能作为衡量操作效率的可靠指标。无论如何,向量加法运算的大 O 复杂度是线性的,即 O(n)。

解决方案 16:

有几种方法

  1. 使用Numpy

import numpy as np
x = np.array([2,3,3])
y = np.array([1,2,6])

print(type(x)) # <class 'numpy.ndarray'>
print(type(y)) # <class 'numpy.ndarray'>

print(x+y) # [3 5 9]
print(type(x+y)) # <class 'numpy.ndarray'>

在上面的代码中,您可以看到输入和输出是 NumPy 数组格式。

import numpy as np
list1=[4,2,2,5]
list2=[2,1,6,7]

print(type(list1)) # <class 'list'>
print(type(list2)) # <class 'list'>

print(np.add(list1,list2)) # [ 6  3  8 12]
print(type(np.add(list1,list2))) # <class 'numpy.ndarray'>

这里,输入和输出的格式不同。

  1. 使用 Numpy添加

import numpy as np
list1=[3, 1, 4]
list2=[0, 9, 7]

print(type(list1)) # <class 'list'>
print(type(list2)) # <class 'list'>

print(np.add(list1, list2).tolist()) # [3, 10, 11]
print(type(np.add(list1, list2).tolist())) # <class 'list'>

在此示例中,我们明确使用to_list()将 NumPy 数组转换为列表类型

  1. 使用Map和Lambda

list1=[1, 3, 3]
list2=[3, 6, 8]

print(map(lambda x,y:x+y, list1, list2)) # <map object at 0x7fea235260a0>
print(list(map(lambda x,y:x+y, list1, list2))) # [4, 9, 11]
  1. 使用zip和列表推导

list1=[3, 1, 3]
list2=[1, 1, 3]

print(type(list1)) # <class 'list'>
print(type(list2)) # <class 'list'>

print(x + y for x, y in zip(list1, list2)) # <generator object <genexpr> at 0x7f755307b6d0>
print(list(x + y for x, y in zip(list1, list2))) # [4, 2, 6]
print(type([x + y for x, y in zip(list1, list2)])) # <class 'list'>

print(sum(x) for x in zip(list1, list2)) # <generator object <genexpr> at 0x7f4c623e76d0>
print(list(sum(x) for x in zip(list1, list2))) # [4, 2, 6]
print(type([sum(x) for x in zip(list1, list2)])) # <class 'list'>
  1. 使用Map和operator.add

from operator import add
list1=[3, 1, 3]
list2=[1, 1, 3]
print(list(map(add, list1, list2))) # [4, 2, 6]

解决方案 17:

a_list = []
b_list = []
for i in range(1,100):
    a_list.append(random.randint(1,100))

for i in range(1,100):
    a_list.append(random.randint(101,200))
[sum(x) for x in zip(a_list , b_list )]

解决方案 18:

list1 = [1, 2, 3]
list2 = [4, 5, 6]
[list1_i + list2_i for list1_i, list2_i in zip(list1 , list2)]
>> [5, 7, 9]

只需添加减法,因为减法只不过是负和。那么解决方案将是:

[list1_i - list2_i for list1_i, list2_i in zip(list1 , list2)]
>> [-3, -3, -3]
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1553  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   27  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   22  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   19  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用