Как выполнить поэлементное умножение двух списков?

Я хочу выполнить поэлементное умножение, чтобы умножить два списка вместе по значению в 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)) =).


person xxjjnn    schedule 22.04.2012    source источник
comment
Почему вы спрашиваете об этом, когда уже сейчас о numpy?   -  person pwuertz    schedule 22.04.2012
comment
И, кстати, это поэлементное умножение, а не скалярное произведение.   -  person pwuertz    schedule 22.04.2012
comment
Альтернатива: map (lambda x, y: x * y, list1, list2) #derp ...   -  person xxjjnn    schedule 23.04.2012


Ответы (15)


Используйте понимание списка, смешанное с zip() :.

[a*b for a,b in zip(lista,listb)]
person gahooa    schedule 22.04.2012
comment
С другой стороны, если они хотят сделать что-то еще, кроме тривиального случая, OP было бы хорошо посоветовать использовать Numpy. - person Henry Gomersall; 23.04.2012
comment
На Python 2 izip () может быть лучшим выбором. - person yak; 23.04.2012
comment
Вы также можете использовать map(lambda x,y:x*y,lista,listb). - person mbomb007; 17.06.2015
comment
Как бы изменился ответ, если бы нам вместо 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) ... и так далее. - person gxyd; 09.07.2017
comment
@gxyd Вы должны задать отдельный вопрос - person mbomb007; 09.08.2018
comment
Просто чтобы добавить к сказанному mbomb007. Чтобы получить это в форме списка, вам нужно будет использовать list(map(lambda x ,y: x * y, lista, listb)) - person FlamePrinz; 18.07.2019
comment
Для меня требуется больше времени, чтобы понять, как архивировать, а затем делать что-то с двумя значениями каждого кортежа, чем, например, решение с map и operator.mul. - person xuiqzy; 03.05.2020

Поскольку вы уже используете 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])
person NPE    schedule 22.04.2012
comment
Может быть, не самый научный, но я сравнил это с ответом gahooa, используя timeit. Numpy на самом деле немного медленнее, чем метод zip. - person Chase Roberts; 15.08.2015
comment
В моем случае, когда списки содержали двоичные значения, решение numpy было намного быстрее, чем использование izip. - person Serendipity; 01.09.2015
comment
Для удобства пользователей, прибывающих сюда из результатов поиска в Google, я включил сравнение времени ниже. - person paddyg; 08.11.2016

Используйте np.multiply (a, b):

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

Вы можете попробовать умножить каждый элемент в цикле. Короткая рука для этого -

ab = [a[i]*b[i] for i in range(len(a))]
person Nate    schedule 07.03.2014
comment
добро пожаловать в stackoverflow! Ответы, содержащие только код, обычно не приветствуются - пожалуйста, добавьте некоторые пояснения, как это решает вопрос спрашивающего. - person Corley Brigman; 07.03.2014
comment
@CorleyBrigman Я не согласен; Существует очень небольшая разница между ответом. Вот способ сделать это: ‹code› и просто ‹code›. В этой конкретной ситуации мало что можно объяснить, кроме того, что этот код решает вашу проблему. - person icedtrees; 07.03.2014
comment
@CorleyBrigman Я не согласен; пример данных с отображением результатов был бы более полезен - person Tjorriemorrie; 14.05.2014
comment
Вот как программист на C, C ++ или Java, который является новичком в Python, решил бы проблему. принятый ответ - это идиоматический Python. - person David Cullen; 08.03.2017
comment
@Tjorriemorrie результаты ясны, поскольку они явно запрашиваются в вопросе. Может быть, было бы неплохо объяснить, как работает понимание списков, или упомянуть, что при этом используется понимание списка, и тогда каждый может найти это, если они этого не знают. - person xuiqzy; 03.05.2020

Еще один ответ:

-1 ... требуется импорт
+1 ... хорошо читается

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

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

выходы [10, 22, 36, 52]

person Petr Vepřek    schedule 20.11.2016
comment
Если вы знаете карту, это действительно удобочитаемое решение! Имеет ли импорт какие-либо негативные последствия, кроме того, что он находится в верхней части файла? (редакторы могут скрывать импорт, если хотят) Насколько я понимаю, он должен быть доступен в каждой версии Python 2 и 3! - person xuiqzy; 03.05.2020
comment
Очень красивое функциональное решение! - person janniks; 27.05.2021

Довольно интуитивно понятный способ сделать это:

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
person Turtleneck    schedule 02.03.2014

вы можете умножать, используя lambda

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

Для больших списков мы можем сделать это по-разному:

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

product_iter_object.next() дает каждый элемент в списке вывода.

Результатом будет длина самого короткого из двух входных списков.

person aady    schedule 21.08.2014

создать массив из единиц; умножьте каждый список на массив; преобразовать массив в список

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]
person litepresence    schedule 23.12.2015

Ответ 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))
person paddyg    schedule 08.11.2016

Можно использовать enumerate.

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

ab = [val * b[i] for i, val in enumerate(a)]
person SuperNova    schedule 04.08.2016

Здесь может быть очень полезна функция 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]
>>>
person sg7    schedule 13.01.2018

Чтобы сохранить тип списка и сделать это в одной строке (после импорта numpy как np, конечно):

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

or

list(np.array(a) * np.array(b))
person mightypile    schedule 02.05.2018

вы можете использовать это для списков одинаковой длины

def lstsum(a, b):
    c=0
    pos = 0
for element in a:
   c+= element*b[pos]
   pos+=1
return c
person WOX GAMER    schedule 20.10.2018

person    schedule
comment
Хотя этот код может решить вопрос, включая объяснение того, как и почему это решает проблему, действительно поможет улучшить качество вашего пост, и, вероятно, приведет к большему количеству голосов. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для человека, который задает его сейчас. Пожалуйста, отредактируйте свой ответ, чтобы добавить пояснения и указать, какие ограничения и предположения применяются. Из отзыва - person double-beep; 24.12.2020