¿Cómo realizar la multiplicación por elementos de dos listas?

137

Quiero realizar una multiplicación sabia de elementos, para multiplicar dos listas juntas por valor en Python, como podemos hacerlo en Matlab.

Así es como lo haría en Matlab.

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

Una comprensión de la lista daría 16 entradas de lista, por cada combinación x * yde xfrom ay yfrom b. No estoy seguro de cómo mapear esto.

Si a alguien le interesa por qué, tengo un conjunto de datos y quiero multiplicarlo por Numpy.linspace(1.0, 0.5, num=len(dataset)) =).

xxjjnn
fuente
44
¿Por qué preguntas esto cuando ya sabes acerca de numpy?
pwuertz
2
Y por cierto, esta es una multiplicación por elementos, este no es un producto de puntos.
pwuertz
3
Alternativa: map (lambda x, y: x * y, list1, list2) #derp ...
xxjjnn

Respuestas:

284

Use una lista de comprensión mezclada con zip():.

[a*b for a,b in zip(lista,listb)]
gahooa
fuente
9
Por otro lado, si quieren hacer algo más que el caso trivial aquí, el OP debería usar Numpy.
Henry Gomersall
1
En Python 2, izip () podría ser una mejor opción.
yak
23
También puedes usar map(lambda x,y:x*y,lista,listb).
mbomb007
¿Cómo cambiaría la respuesta si se nos da en lugar de listbuna lista de elementos de tipo listby se necesita operar para obtener una lista única? Ex. (x, pi, e) con [(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)], cuando se toma (x, pi, e) funciona con (4, 5, 2) y luego (x, pi, e) funciona con (1, 2, 4) ... y así sucesivamente.
gxyd
@gxyd Deberías hacer una pregunta por separado
mbomb007
88

Como ya está utilizando numpy, tiene sentido almacenar sus datos en una numpymatriz en lugar de una lista. Una vez que haces esto, obtienes cosas como productos basados ​​en elementos gratis:

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
fuente
1
Quizás no sea el más científico, pero calculé esto con la respuesta de gahooa usando timeit. Numpy es en realidad un poco más lento que el método zip.
Chase Roberts
1
En mi caso, donde las listas contenían valores binarios, la solución numpy fue mucho más rápida que usar el izip.
Serendipity
Para el beneficio de otros que llegan aquí desde una búsqueda en Google, he incluido una comparación de tiempo a continuación.
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
fuente
21

Puedes intentar multiplicar cada elemento en un bucle. La mano corta para hacer eso es

ab = [a[i]*b[i] for i in range(len(a))]
Nate
fuente
bienvenido a stackoverflow! En general, se desaconsejan las respuestas de solo código; agregue alguna explicación sobre cómo esto resuelve la pregunta del interlocutor.
Corley Brigman
77
@CorleyBrigman no estoy de acuerdo; hay muy poca diferencia entre una respuesta que es "Aquí hay una forma de hacer esto: <code>" y solo "<code>". En esta situación particular, hay poco que explicar aparte de "este código resuelve su problema".
icedtrees
44
@CorleyBrigman no estoy de acuerdo; un ejemplo de datos con la visualización de los resultados sería realmente más útil
Tjorriemorrie
2
Así es como un programador de C, C ++ o Java que es un principiante de Python resolvería el problema. La respuesta aceptada es la idiomática Python.
David Cullen
@Tjorriemorrie los resultados son claros ya que se solicitan explícitamente en la pregunta. quizás una explicación de cómo funcionan las comprensiones de listas podría ser agradable o mencionar que esto hace uso de la comprensión de listas y luego todos pueden buscar eso, si no lo saben.
xuiqzy
10

Otra respuesta más:

-1... requiere importación
+1... es muy legible

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

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

salidas [10, 22, 36, 52]

Petr Vepřek
fuente
Si conoce el mapa, ¡esta es una solución realmente legible! ¿La importación tiene alguna consecuencia negativa además de estar allí en la parte superior del archivo? (los editores pueden ocultar las importaciones si lo desean) Hasta donde puedo ver, ¡debería estar disponible en todas las versiones de python 2 y 3!
xuiqzy
9

Manera bastante intuitiva de hacer esto:

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
Suéter tipo con cuello de tortuga
fuente
9

puedes multiplicar usando lambda

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

Para listas grandes, podemos hacerlo de la siguiente manera:

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

product_iter_object.next() da cada uno de los elementos en la lista de salida.

La salida sería la longitud de la más corta de las dos listas de entrada.

aady
fuente
4

crear una variedad de unos; multiplicar cada lista por la matriz; convertir matriz a una 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]
presencia lite
fuente
3

La respuesta de gahooa es correcta para la pregunta tal como está redactada en el encabezado, pero si las listas ya tienen formato numpy o más de diez, será MUCHO más rápido (3 órdenes de magnitud) y más legible, para hacer una multiplicación numpy simple como lo sugiere NPE. Tengo estos horarios:

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

es decir, del siguiente programa de prueba.

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

Puede usar enumerate.

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

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

La mapfunción puede ser muy útil aquí. Usando mappodemos aplicar cualquier función a cada elemento de un iterable.

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

Por supuesto:

map(f, iterable)

es equivalente a

[f(x) for x in iterable]

Para que podamos obtener nuestra solución a través de:

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

En Python 2.x map()significa: aplicar una función a cada elemento de un iterable y construir una nueva lista. En Python 3.x, mapconstruya iteradores en lugar de listas.

En lugar de my_mulpodríamos usar 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+

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

Tenga en cuenta que, dado que map()construye un iterador, utilizamos un *operador de desempaquetado iterable para obtener una lista. El enfoque de desempaquetado es un poco más rápido que el listconstructor:

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

Para mantener el tipo de lista y hacerlo en una línea (después de importar numpy como np, por supuesto):

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

o

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

puedes usar esto para listas de la misma longitud

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