Come eseguire la moltiplicazione degli elementi in due elenchi?


137

Voglio eseguire una moltiplicazione saggia elemento, moltiplicare due liste insieme per valore in Python, come possiamo fare in Matlab.

È così che lo farei in Matlab.

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

Una comprensione di lista darebbe 16 voci di lista, per ogni combinazione x * ydi xda ae yda b. Non sono sicuro di come mapparlo.

Se qualcuno è interessato al perché, ho un set di dati e voglio moltiplicarlo per Numpy.linspace(1.0, 0.5, num=len(dataset)) =).


4
Perché lo stai chiedendo già ora riguardo al numpy?
pwuertz,

2
A proposito, questa è una moltiplicazione degli elementi, non si tratta di un prodotto a punti.
pwuertz,

3
Alternativa: mappa (lambda x, y: x * y, list1, list2) #derp ...
xxjjnn

Risposte:


284

Utilizzare una comprensione dell'elenco unita a zip():.

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

9
D'altra parte, se vogliono fare qualcos'altro oltre al semplice caso qui, l'OP sarebbe ben consigliato di usare Numpy.
Henry Gomersall,

1
Su Python 2 izip () potrebbe essere una scelta migliore.
yak,

23
Puoi anche usare map(lambda x,y:x*y,lista,listb).
mbomb007,

Come cambierebbe la risposta se ci viene fornito invece di listbun elenco piuttosto di elementi di tipo listbe dobbiamo operare per ottenere un unico elenco. Ex. (x, pi, e) con [(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)], quando preso (x, pi, e) operato con (4, 5, 2) e poi (x, pi, e) operato con (1, 2, 4) ... ecc.
gxyd,

@gxyd Dovresti porre una domanda separata
mbomb007,

88

Dal momento che stai già utilizzando numpy, ha senso archiviare i tuoi dati in un numpyarray anziché in un elenco. Una volta fatto questo, ottieni cose come prodotti a livello di elementi gratuiti:

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
Forse non il più scientifico, ma ho cronometrato questo con la risposta di gahooa usando timeit. Numpy è in realtà leggermente più lento del metodo zip.
Chase Roberts,

1
Nel mio caso, in cui gli elenchi contenevano valori binari, la soluzione numpy era molto più veloce rispetto all'utilizzo di izip.
Serendipity,

A beneficio di altri che arrivano qui da una ricerca su Google, ho incluso un confronto timeit di seguito.
Paddyg,

31

Usa np.multiply (a, b):

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

21

Puoi provare a moltiplicare ogni elemento in un ciclo. La scorciatoia per farlo è

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

benvenuto in StackOverflow! Le risposte di solo codice sono generalmente sconsigliate - per favore aggiungi qualche spiegazione su come questo risolve la domanda dell'interrogatore.
Corley Brigman

7
@CorleyBrigman Non sono d'accordo; c'è una differenza molto piccola tra una risposta che è "Ecco un modo per farlo: <code>" e solo "<code>". In questa situazione particolare, c'è poco da spiegare oltre a "questo codice risolve il problema".
Icedtrees,

4
@CorleyBrigman Non sono d'accordo; un esempio di dati con la visualizzazione dei risultati sarebbe effettivamente più utile
Tjorriemorrie

2
Ecco come un programmatore C, C ++ o Java che è un principiante di Python risolverà il problema. La risposta accettata è Python idiomatica.
David Cullen,

@Tjorriemorrie i risultati sono chiari in quanto esplicitamente richiesti nella domanda. forse una spiegazione di come funziona la comprensione dell'elenco potrebbe essere piacevole o menzionare che questo fa uso della comprensione dell'elenco e quindi tutti possono cercarlo, se non lo conoscono.
xuiqzy,

10

Ancora un'altra risposta:

-1... richiede importazione
+1... è molto leggibile

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

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

uscite [10, 22, 36, 52]


Se conosci la mappa, questa è una soluzione davvero leggibile! L'importazione ha conseguenze negative oltre a essere presente nella parte superiore del file? (gli editor possono nascondere le importazioni se lo desiderano) Per quanto posso vedere, dovrebbe essere disponibile in ogni versione di Python 2 e 3!
xuiqzy,

9

Modo abbastanza intuitivo per farlo:

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

puoi moltiplicare usando lambda

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

4

Per elenchi di grandi dimensioni, possiamo farlo nell'iter:

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

product_iter_object.next() fornisce ciascuno degli elementi nell'elenco di output.

L'output sarebbe la lunghezza del più breve dei due elenchi di input.


4

crearne una serie; moltiplicare ogni elenco per l'array; converti l'array in un elenco

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

la risposta di gahooa è corretta per la domanda come formulata nell'intestazione, ma se gli elenchi sono già in formato intorpidito o maggiore di dieci, sarà MOLTO più veloce (3 ordini di grandezza) oltre che più leggibile, per fare una semplice moltiplicazione numpy come suggerito da NPE. Ottengo questi tempi:

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

cioè dal seguente programma di test.

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

Può usare enumerare.

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

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

3

La mapfunzione può essere molto utile qui. utilizzandomap possiamo applicare qualsiasi funzione a ciascun elemento di un iterabile.

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

Ovviamente:

map(f, iterable)

è equivalente a

[f(x) for x in iterable]

Quindi possiamo ottenere la nostra soluzione tramite:

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

In Python 2.x map()significa: applicare una funzione a ciascun elemento di un iterabile e costruire un nuovo elenco. In Python 3.x,map crea iteratori anziché elenchi.

Invece di my_mulpotremmo usare mul operatore

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

Si noti che dal momento che map()costruisce un iteratore utilizziamo un *operatore iterable di decompressione per ottenere un elenco. L'approccio di decompressione è leggermente più veloce del listcostruttore:

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

1

Per mantenere il tipo di elenco e farlo in una riga (ovviamente dopo aver importato numpy come np):

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

o

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

0

puoi usarlo per elenchi della stessa lunghezza

def lstsum(a, b):
    c=0
    pos = 0
for element in a:
   c+= element*b[pos]
   pos+=1
return c
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.