Як виконати елементне множення двох списків?


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
Чому ти це питаєш, коли вже говориш про оніміння?
pwuertz

2
І, до речі, це елементарне множення, це не крапковий продукт.
pwuertz

3
Альтернатива: карта (лямбда х, у: х * у, список1, список2) #derp ...
xxjjnn

Відповіді:


284

Використовуйте розуміння списку, змішане з zip():.

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

9
З іншого боку, якщо вони хочуть зробити щось інше за межі тривіального випадку, тут ОП радимо б використовувати Numpy.
Генрі Гомерсалл

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.
Чейз Робертс

1
У моєму випадку, коли списки містили двійкові значення, рішення numpy було набагато швидшим, ніж використання izip.
Serendipity

Для користі інших, які приїжджають сюди з google search, я включив порівняння timeit нижче.
піддіг

31

Використовуйте np.multiply (a, b):

import numpy as np
a = [1,2,3,4]
b = [2,3,4,5]
np.multiply(a,b)

21

Можна спробувати множити кожен елемент у циклі. Коротка рука для цього є

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

Ласкаво просимо в stackoverflow! відповіді, що стосуються лише коду, як правило, не рекомендують. Будь ласка, додайте пояснення, як це вирішує питання запитувача.
Корлі Бригман

7
@CorleyBrigman Я не згоден; Існує дуже мала різниця між відповіддю, який є "Ось спосіб зробити це: <код>" і просто "<код>". У цій конкретній ситуації мало що можна пояснити, окрім "цей код вирішує вашу проблему".
icedtrees

4
@CorleyBrigman Я не згоден; приклад даних із відображенням результатів насправді був би кориснішим
Tjorriemorrie

2
Ось так, C, C ++ або Java-програміст, який є початківцем Python, вирішив би проблему. Загальноприйнятий відповідь ідіоматічен Python.
Девід Каллен

@Tjorriemorrie результати зрозумілі, оскільки вони прямо запитуються у запитанні. можливо, пояснення того, як працює розуміння списків, може бути приємним, або згадати, що для цього використовується розуміння списку, і тоді всі можуть подивитися на це, якщо вони цього не знають.
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

9

Досить інтуїтивно зрозумілий спосіб:

a = [1,2,3,4]
b = [2,3,4,5]
ab = []                        #Create empty list
for i in range(0, len(a)):
     ab.append(a[i]*b[i])      #Adds each element to the list

9

ви можете множити, використовуючи lambda

foo=[1,2,3,4]
bar=[1,2,5,55]
l=map(lambda x,y:x*y,foo,bar)

4

Для великих списків ми можемо це зробити ітерально:

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 порядки), а також більш читабельним, робити просте множення чисел, як це запропоновано 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

Можна використовувати перерахування.

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

ab = [val * b[i] for i, val in enumerate(a)]

3

Тут mapфункція може бути дуже корисною. За допомогою mapми можемо застосувати будь-яку функцію до кожного елементу, який можна повторити.

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.