Como executar a multiplicação por elementos de duas listas?

137

Quero executar uma multiplicação por elementos, multiplicar duas listas por valor em Python, como podemos fazer no Matlab.

É assim que eu faria no Matlab.

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

Uma compreensão da lista daria 16 entradas na lista, para cada combinação x * yde xfrom ae yfrom b. Não sabe como mapear isso.

Se alguém estiver interessado no motivo, tenho um conjunto de dados e quero multiplicá-lo por Numpy.linspace(1.0, 0.5, num=len(dataset)) =).

xxjjnn
fonte
4
Por que você está perguntando isso quando você já está entorpecido?
Pwuertz
2
E, a propósito, isso é multiplicação por elementos, este não é um produto escalar.
Pwuertz
3
Alternativa: map (lambda x, y: x * y, list1, list2) #derp ...
xxjjnn

Respostas:

284

Use uma compreensão de lista combinada com zip():.

[a*b for a,b in zip(lista,listb)]
gahooa
fonte
9
Por outro lado, se eles quiserem fazer qualquer outra coisa além do caso trivial aqui, o OP deve usar o Numpy.
precisa
1
No Python 2, izip () poderia ser uma escolha melhor.
simples
23
Você também pode usar map(lambda x,y:x*y,lista,listb).
mbomb007
Como a resposta mudaria se for dada, em vez de listbuma lista de elementos do tipo, listbe precisarmos operar para obter uma única lista. Ex. (x, pi, e) com [(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)], quando tomado (x, pi, e) operado com (4, 5, 2) e depois (x, pi, e) operado com (1, 2, 4) ... etc.
gxyd
@gxyd Você deve fazer uma pergunta separada
mbomb007
87

Como você já está usando numpy, faz sentido armazenar seus dados em uma numpymatriz, e não em uma lista. Depois de fazer isso, você obtém itens como produtos baseados em elementos de graça:

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
fonte
1
Talvez não seja o mais científico, mas cronometrei isso contra a resposta de gahooa usando timeit. Numpy é realmente um pouco mais lento que o método zip.
Perseguição Roberts
1
No meu caso, onde as listas continham valores binários, a solução numpy era muito mais rápida do que usar o izip.
Serendipity
Para o benefício de outras pessoas que chegam aqui de uma pesquisa no google, incluí uma comparação de tempo abaixo.
8286 paddyg
31

Use np.multiply (a, b):

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

Você pode tentar multiplicar cada elemento em um loop. A mão curta para fazer isso é

ab = [a[i]*b[i] for i in range(len(a))]
Nate
fonte
bem-vindo ao stackoverflow! as respostas somente de código geralmente são desencorajadas - adicione algumas explicações sobre como isso resolve a pergunta do questionador.
Corley Brigman
7
@CorleyBrigman Eu discordo; há muito pouca diferença entre uma resposta que é "Aqui está uma maneira de fazer isso: <code>" e apenas "<code>". Nessa situação específica, há pouco a explicar além de "esse código resolve seu problema".
Icedtrees
4
@CorleyBrigman Eu discordo; um exemplo de dados com exibindo os resultados na verdade seria mais útil
Tjorriemorrie
2
É assim que um programador em C, C ++ ou Java, novato em Python, resolveria o problema. A resposta aceita é Python idiomático.
David Cullen
@Tjorriemorrie, os resultados são claros, pois são explicitamente solicitados na pergunta. talvez uma explicação de como as compreensões de lista funcionem poderia ser boa ou mencionar que isso faz uso da compreensão de lista e todos poderão procurar isso, se não souberem.
xuiqzy
10

Ainda outra resposta:

-1... requer importação
+1... é muito legível

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

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

saídas [10, 22, 36, 52]

Petr Vepřek
fonte
Se você conhece o mapa, esta é uma solução realmente legível! A importação tem alguma consequência negativa além de estar na parte superior do arquivo? (os editores podem ocultar as importações, se quiserem) Até onde eu vejo, ele deve estar disponível em todas as versões python 2 e 3!
xuiqzy
9

Maneira bastante intuitiva de fazer isso:

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
Gola alta
fonte
9

você pode multiplicar usando lambda

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

Para listas grandes, podemos fazê-lo da maneira iterativa:

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

product_iter_object.next() fornece cada um dos elementos na lista de saída.

A saída seria o comprimento da menor das duas listas de entrada.

aady
fonte
4

crie uma matriz de unidades; multiplique cada lista vezes a matriz; converter matriz em uma lista

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]
presença
fonte
3

A resposta de gahooa está correta para a pergunta formulada no cabeçalho, mas se as listas já tiverem um formato numpy ou maior que dez, será MUITO mais rápido (3 ordens de grandeza) e mais legível, para fazer a multiplicação numpy simples, conforme sugerido por NPE. Eu recebo estes horários:

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

ou seja, a partir do seguinte programa de teste.

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
fonte
3

Pode usar enumerar.

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

ab = [val * b[i] for i, val in enumerate(a)]
Super Nova
fonte
3

A mapfunção pode ser muito útil aqui. Usando mappodemos aplicar qualquer função a cada elemento de um iterável.

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

Claro:

map(f, iterable)

é equivalente a

[f(x) for x in iterable]

Para que possamos obter nossa solução via:

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

No Python 2.x map()significa: aplique uma função a cada elemento de um iterável e construa uma nova lista. No Python 3.x, mapconstrua iteradores em vez de listas.

Em vez de my_mulpodermos usar o muloperador

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 ou superior

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

Observe que, como map()constrói um iterador, usamos o *operador de descompactação iterável para obter uma lista. A abordagem de descompactação é um pouco mais rápida que o listconstrutor:

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

Para manter o tipo de lista e faça-o em uma linha (depois de importar o numpy como np, é claro):

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

ou

list(np.array(a) * np.array(b))
mightypile
fonte
0

você pode usar isso para listas do mesmo tamanho

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