Jak przeprowadzić elementarne mnożenie dwóch list?

137

Chcę wykonać mądre mnożenie elementów, aby pomnożyć razem dwie listy przez wartość w Pythonie, tak jak możemy to zrobić w Matlabie.

Tak bym to zrobił w Matlabie.

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

Lista rozumienie dałoby 16 Lista pozycji, dla każdej kombinacji x * yz xod ai yod b. Nie wiem, jak to zmapować.

Jeśli ktoś jest zainteresowany dlaczego, mam zbiór danych i chcę go pomnożyć przez Numpy.linspace(1.0, 0.5, num=len(dataset)) =).

xxjjnn
źródło
4
Dlaczego o to pytasz, skoro już teraz mówisz o numpy?
pwuertz
2
Nawiasem mówiąc, to jest mnożenie elementarne, to nie jest iloczyn skalarny.
pwuertz
3
Alternatywa: map (lambda x, y: x * y, list1, list2) #derp ...
xxjjnn

Odpowiedzi:

284

Użyj zrozumieniem zmieszanej z listy zip().

[a*b for a,b in zip(lista,listb)]
gahooa
źródło
9
Z drugiej strony, jeśli chcą zrobić coś innego poza trywialnym przypadkiem w tym przypadku, dobrze byłoby, gdyby OP korzystał z Numpy.
Henry Gomersall
1
W Pythonie 2 izip () może być lepszym wyborem.
jaka
23
Możesz także użyć map(lambda x,y:x*y,lista,listb).
mbomb007
Jak zmieniłaby się odpowiedź, gdyby zamiast listbraczej listy elementów typu listbpodano nam i musimy operować, aby otrzymać jedną listę. Dawny. (x, pi, e) z [(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)], gdy wzięty (x, pi, e) działa z (4, 5, 2), a następnie (x, pi, e) działa z (1, 2, 4) ... tak dalej.
gxyd
@gxyd Powinieneś zadać osobne pytanie
mbomb007
87

Ponieważ już używasz numpy, sensowne jest przechowywanie danych w numpytablicy, a nie na liście. Gdy to zrobisz, otrzymasz bezpłatnie takie rzeczy, jak produkty oparte na elementach:

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])
NPE
źródło
1
Może nie najbardziej naukowy, ale porównałem to z odpowiedzią gahooa, używając timeit. Numpy jest właściwie nieco wolniejszy niż metoda zip.
Chase Roberts
1
W moim przypadku, gdy listy zawierały wartości binarne, rozwiązanie numpy było znacznie szybsze niż użycie izipa.
Serendipity
Dla dobra innych przybywających tutaj z wyszukiwarki Google, poniżej zamieściłem porównanie czasu.
paddyg
31

Użyj np.multiply (a, b):

import numpy as np
a = [1,2,3,4]
b = [2,3,4,5]
np.multiply(a,b)
Brisa
źródło
21

Możesz spróbować pomnożyć każdy element w pętli. Krótka ręka za to

ab = [a[i]*b[i] for i in range(len(a))]
Nate
źródło
witamy w stackoverflow! odpowiedzi zawierające tylko kod są generalnie odradzane - prosimy o wyjaśnienie, w jaki sposób rozwiązuje to pytanie pytającego.
Corley Brigman
7
@CorleyBrigman Nie zgadzam się; jest bardzo mała różnica między odpowiedzią, która brzmi „Oto sposób na zrobienie tego: <kod>” a po prostu „<kod>”. W tej konkretnej sytuacji niewiele jest do wyjaśnienia poza „tym kodem rozwiązuje problem”.
icedtrees
4
@CorleyBrigman Nie zgadzam się; przykładowe dane z wyświetlaniem wyników byłyby faktycznie bardziej pomocne
Tjorriemorrie
2
W ten sposób programista C, C ++ lub Java, który jest nowicjuszem w Pythonie, rozwiązałby problem. Odpowiedź akceptowana jest idiomatyczne Python.
David Cullen
@Tjorriemorrie wyniki są jasne, ponieważ są wyraźnie wymagane w pytaniu. może wyjaśnienie, jak działają wyrażenia listowe, mogłoby być miłe lub wspomnienie, że wykorzystuje to rozumienie list, a wtedy każdy może to sprawdzić, jeśli tego nie wie.
xuiqzy
10

Jeszcze inna odpowiedź:

-1... wymaga importu
+1... jest bardzo czytelny

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

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

wyjścia [10, 22, 36, 52]

Petr Vepřek
źródło
Jeśli znasz mapę, to naprawdę czytelne rozwiązanie! Czy import ma jakiekolwiek negatywne konsekwencje poza znajdowaniem się na początku pliku? (redaktorzy mogą ukryć import, jeśli chcą) O ile wiem, powinno być dostępne w każdej wersji Pythona 2 i 3!
xuiqzy
9

Dość intuicyjny sposób na zrobienie tego:

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
Golf
źródło
9

możesz pomnożyć używając lambda

foo=[1,2,3,4]
bar=[1,2,5,55]
l=map(lambda x,y:x*y,foo,bar)
Benzoes
źródło
4

W przypadku dużych list możemy to zrobić iteracyjnie:

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

product_iter_object.next() podaje każdy element na liście wyników.

Wynik byłby długością krótszej z dwóch list wejściowych.

gotowy
źródło
4

utwórz tablicę jedynek; pomnóż każdą listę razy tablicę; przekonwertować tablicę na listę

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]
litepresence
źródło
3

Odpowiedź gahooa jest poprawna dla pytania sformułowanego w nagłówku, ale jeśli listy są już w formacie numpy lub są większe niż dziesięć, będzie DUŻO szybsze (3 rzędy wielkości), a także bardziej czytelne, aby wykonać proste mnożenie liczbowe, jak sugeruje NPE. Otrzymuję te czasy:

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

tj. z następującego programu testowego.

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))
paddyg
źródło
3

Może użyć enumerate.

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

ab = [val * b[i] for i, val in enumerate(a)]
SuperNova
źródło
3

Ta mapfunkcja może być tutaj bardzo przydatna. Używając mapmożemy zastosować dowolną funkcję do każdego elementu iterowalnego.

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

Oczywiście:

map(f, iterable)

jest równa

[f(x) for x in iterable]

Więc możemy uzyskać nasze rozwiązanie poprzez:

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

W Pythonie 2.x map()oznacza: zastosuj funkcję do każdego elementu iterowalnego i skonstruuj nową listę. W Pythonie 3.x mapkonstruuj iteratory zamiast list.

Zamiast tego my_mulmoglibyśmy użyć muloperatora

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

Zwróć uwagę, że ponieważ map()konstruuje iterator, używamy *iterowalnego operatora rozpakowywania, aby uzyskać listę. Rozpakowywanie jest nieco szybsze niż listkonstruktor:

>>> list(map(mul,a,b))
[2, 6, 12, 20]
>>>
sg7
źródło
1

Aby zachować typ listy i zrób to w jednej linii (oczywiście po zaimportowaniu numpy jako np):

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

lub

list(np.array(a) * np.array(b))
mightypile
źródło
0

możesz tego użyć do list o tej samej długości

def lstsum(a, b):
    c=0
    pos = 0
for element in a:
   c+= element*b[pos]
   pos+=1
return c
WOX GAMER
źródło