วิธีดำเนินการคูณสององค์ประกอบที่ชาญฉลาดได้อย่างไร


137

ฉันต้องการทำการคูณองค์ประกอบที่ชาญฉลาดเพื่อคูณสองรายการด้วยค่าใน Python เหมือนกับที่เราสามารถทำได้ใน Matlab

นี่คือวิธีที่ฉันจะทำใน Matlab

a = [1,2,3,4]
b = [2,3,4,5]
a .* b = [2, 6, 12, 20]

ความเข้าใจจะให้รายการ 16 รายการรายการสำหรับการรวมกันทุกx * yของxจากaและจากy bไม่แน่ใจวิธีแผนที่นี้

Numpy.linspace(1.0, 0.5, num=len(dataset)) =)หากใครสนใจว่าทำไมฉันมีชุดข้อมูลและต้องการที่จะคูณด้วย


4
ทำไมคุณถามเรื่องนี้เมื่อคุณตอนนี้เกี่ยวกับ numpy แล้ว?
pwuertz

2
นี่คือการคูณองค์ประกอบที่ฉลาดนี่ไม่ใช่ผลิตภัณฑ์ดอท
pwuertz

3
ทางเลือก: แผนที่ (แลมบ์ดา x, y: x * y, list1, list2) #derp ...
xxjjnn

คำตอบ:


284

ใช้รายการความเข้าใจผสมกับzip():

[a*b for a,b in zip(lista,listb)]

9
ในทางกลับกันหากพวกเขาต้องการทำสิ่งอื่นนอกเหนือจากเรื่องเล็กน้อยที่นี่ OP ควรได้รับการแนะนำให้ใช้ Numpy
Henry Gomersall

1
ใน Python 2 izip () อาจเป็นทางเลือกที่ดีกว่า
จามรี

23
map(lambda x,y:x*y,lista,listb)นอกจากนี้คุณยังสามารถใช้
mbomb007

คำตอบจะเปลี่ยนไปอย่างไรถ้าเราได้รับแทนที่จะlistbเป็นรายการชนิดขององค์ประกอบที่ค่อนข้างlistbจะได้รับและเราจำเป็นต้องดำเนินการเพื่อให้ได้รายการเดียว อดีต (x, pi, e) กับ [(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)], เมื่อถ่าย (x, pi, e) ทำงานด้วย (4, 5, 2) และจากนั้น (x, pi, e) ทำงานด้วย (1, 2, 4) ... เป็นต้น
gxyd

@gxyd คุณควรถามคำถามแยกต่างหาก
mbomb007

87

เนื่องจากคุณใช้อยู่แล้วคุณnumpyควรเก็บข้อมูลของคุณไว้ในnumpyอาร์เรย์แทนที่จะเป็นรายการ เมื่อคุณทำเช่นนี้คุณจะได้รับผลิตภัณฑ์อย่างชาญฉลาดฟรี:

In [1]: import numpy as np

In [2]: a = np.array([1,2,3,4])

In [3]: b = np.array([2,3,4,5])

In [4]: a * b
Out[4]: array([ 2,  6, 12, 20])

1
อาจไม่ใช่ทางวิทยาศาสตร์มากที่สุด แต่ฉันหมดเวลากับคำตอบของ gahooa โดยใช้ timeit Numpy นั้นช้ากว่าวิธี zip เล็กน้อย
Chase Roberts

1
ในกรณีของฉันที่รายการมีค่าไบนารีโซลูชัน numpy นั้นเร็วกว่าการใช้ izip มาก
Serendipity

เพื่อประโยชน์ของผู้อื่นที่มาที่นี่จากการค้นหาของ Google ฉันได้รวมการเปรียบเทียบเวลาไว้ด้านล่าง
paddyg


21

คุณสามารถลองคูณองค์ประกอบในการวนซ้ำ มือสั้น ๆ ที่ทำสิ่งนั้นคือ

ab = [a[i]*b[i] for i in range(len(a))]

ยินดีต้อนรับสู่ stackoverflow! โดยทั่วไปคำตอบแบบรหัสเท่านั้นจะหมดกำลังใจ - โปรดเพิ่มคำอธิบายเกี่ยวกับวิธีการแก้ปัญหาของคำถาม
Corley Brigman

7
@CorleyBrigman ฉันไม่เห็นด้วย มีความแตกต่างกันเล็กน้อยระหว่างคำตอบซึ่งเป็น "นี่คือวิธีการทำสิ่งนี้: <code>" และเพียงแค่ "<code>" ในสถานการณ์นี้มีเพียงเล็กน้อยที่จะอธิบายนอกเหนือจาก "รหัสนี้แก้ปัญหาของคุณ"
icedtrees

4
@CorleyBrigman ฉันไม่เห็นด้วย ข้อมูลตัวอย่างที่แสดงผลลัพธ์จะมีประโยชน์มากกว่าจริง ๆ
Tjorriemorrie

2
นี่คือวิธีที่โปรแกรมเมอร์ C, C ++ หรือ Java ที่เป็น Python สามเณรจะแก้ปัญหา คำตอบที่ได้รับการยอมรับเป็นงูหลามสำนวน
David Cullen

@Tjorriemorrie ผลลัพธ์มีความชัดเจนเนื่องจากมีการร้องขออย่างชัดเจนในคำถาม บางทีคำอธิบายวิธีการทำงานของ list comprehensions อาจดีหรือกล่าวถึงสิ่งนี้ทำให้การใช้ list comprehension นั้นทุกคนสามารถค้นหาได้ถ้าพวกเขาไม่รู้
xuiqzy

10

อีกคำตอบหนึ่ง:

-1... ต้องการการนำเข้า
+1... สามารถอ่านได้มาก

import operator
a = [1,2,3,4]
b = [10,11,12,13]

list(map(operator.mul, a, b))

เอาต์พุต [10, 22, 36, 52]


ถ้าคุณรู้แผนที่นี่เป็นทางออกที่อ่านง่ายจริงๆ! การนำเข้ามีผลกระทบเชิงลบนอกเหนือจากการอยู่ที่ด้านบนของไฟล์หรือไม่ (บรรณาธิการสามารถซ่อนการนำเข้าได้ถ้าต้องการ) เท่าที่ฉันเห็นมันควรจะมีให้ใน python 2 และ 3 ทุกเวอร์ชั่น!
xuiqzy



4

สำหรับรายการขนาดใหญ่เราสามารถทำ iter-way:

product_iter_object = itertools.imap(operator.mul, [1,2,3,4], [2,3,4,5])

product_iter_object.next() ให้แต่ละองค์ประกอบในรายการเอาท์พุท

เอาต์พุตจะเป็นความยาวของรายการอินพุตสองรายการที่สั้นลง


4

สร้างอาร์เรย์ของคน คูณแต่ละรายการคูณอาร์เรย์ แปลงอาร์เรย์เป็นรายการ

import numpy as np

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

c = (np.ones(len(a))*a*b).tolist()

[2.0, 6.0, 12.0, 20.0]

3

คำตอบของ gahooa นั้นถูกต้องสำหรับคำถามที่เป็นวลีในหัวเรื่อง แต่ถ้ารายการมีรูปแบบที่มีจำนวนมากหรือมากกว่าสิบรายการจะเร็วขึ้นมาก (3 คำสั่งของขนาด) และอ่านได้ง่ายขึ้นเพื่อทำการคูณ numpy อย่างที่แนะนำโดย NPE ฉันได้รับการกำหนดเวลาเหล่านี้:

0.0049ms -> N = 4, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0075ms -> N = 4, a = [i for i in range(N)], c = a * b
0.0167ms -> N = 4, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0013ms -> N = 4, a = np.arange(N), c = a * b
0.0171ms -> N = 40, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0095ms -> N = 40, a = [i for i in range(N)], c = a * b
0.1077ms -> N = 40, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0013ms -> N = 40, a = np.arange(N), c = a * b
0.1485ms -> N = 400, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0397ms -> N = 400, a = [i for i in range(N)], c = a * b
1.0348ms -> N = 400, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0020ms -> N = 400, a = np.arange(N), c = a * b

เช่นจากโปรแกรมทดสอบต่อไปนี้

import timeit

init = ['''
import numpy as np
N = {}
a = {}
b = np.linspace(0.0, 0.5, len(a))
'''.format(i, j) for i in [4, 40, 400] 
                  for j in ['[i for i in range(N)]', 'np.arange(N)']]

func = ['''c = [a*b for a,b in zip(a, b)]''',
'''c = a * b''']

for i in init:
  for f in func:
    lines = i.split('\n')
    print('{:6.4f}ms -> {}, {}, {}'.format(
           timeit.timeit(f, setup=i, number=1000), lines[2], lines[3], f))


3

mapฟังก์ชั่นจะมีประโยชน์มากที่นี่ ใช้mapเราสามารถใช้ฟังก์ชั่นใด ๆ กับองค์ประกอบของ iterable แต่ละ

Python 3.x

>>> def my_mul(x,y):
...     return x*y
...
>>> a = [1,2,3,4]
>>> b = [2,3,4,5]
>>>
>>> list(map(my_mul,a,b))
[2, 6, 12, 20]
>>>

แน่นอน:

map(f, iterable)

เทียบเท่ากับ

[f(x) for x in iterable]

เพื่อให้เราสามารถแก้ปัญหาของเราผ่าน:

>>> [my_mul(x,y) for x, y in zip(a,b)]
[2, 6, 12, 20]
>>>

ใน Python 2.x map()หมายถึง: ใช้ฟังก์ชั่นกับแต่ละองค์ประกอบของการทำซ้ำและสร้างรายการใหม่ ใน Python 3.x ให้mapสร้างตัววนซ้ำแทนรายการ

แทนที่จะmy_mulใช้ mulโอเปอเรเตอร์

Python 2.7

>>>from operator import mul # import mul operator
>>>a = [1,2,3,4]
>>>b = [2,3,4,5]
>>>map(mul,a,b)
[2, 6, 12, 20]
>>>

Python 3.5+

>>> from operator import mul
>>> a = [1,2,3,4]
>>> b = [2,3,4,5]
>>> [*map(mul,a,b)]
[2, 6, 12, 20]
>>>

โปรดทราบว่าตั้งแต่map()สร้างตัววนซ้ำเราจึงใช้*ตัวดำเนินการแกะกล่องที่ซ้ำได้เพื่อรับรายการ วิธีการคลายออกจะเร็วขึ้นเล็กน้อยจากตัวlistสร้าง:

>>> list(map(mul,a,b))
[2, 6, 12, 20]
>>>

1

เพื่อรักษาชนิดรายการและทำในหนึ่งบรรทัด (หลังจากนำเข้า numpy เป็น np แน่นอน):

list(np.array([1,2,3,4]) * np.array([2,3,4,5]))

หรือ

list(np.array(a) * np.array(b))

0

คุณสามารถใช้สิ่งนี้สำหรับรายการที่มีความยาวเท่ากัน

def lstsum(a, b):
    c=0
    pos = 0
for element in a:
   c+= element*b[pos]
   pos+=1
return c
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.