Comment effectuer une multiplication élémentaire de deux listes?


137

Je veux effectuer une multiplication élément par élément, multiplier deux listes par valeur en Python, comme nous pouvons le faire dans Matlab.

C'est comme ça que je le ferais dans Matlab.

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

Une compréhension de liste donnerait 16 entrées de liste, pour chaque combinaison x * yde xfrom aet yfrom b. Je ne sais pas comment cartographier cela.

Si quelqu'un est intéressé par la raison, j'ai un ensemble de données et je veux le multiplier par Numpy.linspace(1.0, 0.5, num=len(dataset)) =).


4
Pourquoi demandez-vous cela alors que vous avez déjà parlé de numpy?
pwuertz

2
Et au fait, il s'agit d'une multiplication élémentaire, ce n'est pas un produit scalaire.
pwuertz

3
Alternative: map (lambda x, y: x * y, list1, list2) #derp ...
xxjjnn

Réponses:


284

Utilisez une compréhension de liste mélangée avec zip():.

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

9
D'un autre côté, s'ils veulent faire autre chose que le cas trivial ici, l'OP serait bien avisé d'utiliser Numpy.
Henry Gomersall

1
Sur Python 2, izip () pourrait être un meilleur choix.
yak

23
Vous pouvez également utiliser map(lambda x,y:x*y,lista,listb).
mbomb007

Comment la réponse changerait-elle si on nous donne plutôt listbqu'une liste d'éléments de type listbet que nous devons opérer pour obtenir une liste unique. Ex. (x, pi, e) avec [(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)], lorsqu'il est pris (x, pi, e) opéré avec (4, 5, 2) puis (x, pi, e) opéré avec (1, 2, 4) ... ainsi de suite.
gxyd le

@gxyd Vous devriez poser une question distincte
mbomb007

88

Puisque vous utilisez déjà numpy, il est logique de stocker vos données dans un numpytableau plutôt que dans une liste. Une fois que vous faites cela, vous obtenez des choses comme des produits élémentaires gratuitement:

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
Peut-être pas le plus scientifique, mais j'ai chronométré cela par rapport à la réponse de gahooa en utilisant timeit. Numpy est en fait légèrement plus lent que la méthode zip.
Chase Roberts

1
Dans mon cas, où les listes contenaient des valeurs binaires, la solution numpy était beaucoup plus rapide que l'utilisation de l'izip.
Serendipity

Pour le bénéfice des autres arrivant ici à partir d'une recherche Google, j'ai inclus une comparaison timeit ci-dessous.
paddyg

31

Utilisez np.multiply (a, b):

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

21

Vous pouvez essayer de multiplier chaque élément dans une boucle. La petite main pour faire cela est

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

Bienvenue sur stackoverflow! Les réponses basées uniquement sur le code sont généralement déconseillées - veuillez ajouter quelques explications sur la façon dont cela résout la question de l'interrogateur.
Corley Brigman

7
@CorleyBrigman Je ne suis pas d'accord; il y a très peu de différence entre une réponse qui est "Voici une façon de faire ceci: <code>" et juste "<code>". Dans cette situation particulière, il n'y a pas grand-chose à expliquer à part «ce code résout votre problème».
icedtrees

4
@CorleyBrigman Je ne suis pas d'accord; un exemple de données avec l'affichage des résultats serait en fait plus utile
Tjorriemorrie

2
C'est ainsi qu'un programmeur C, C ++ ou Java novice en Python résoudrait le problème. La réponse acceptée est Python idiomatique.
David Cullen

@Tjorriemorrie les résultats sont clairs car ils sont explicitement demandés dans la question. peut-être qu'une explication du fonctionnement de la compréhension de liste pourrait être agréable ou mentionner que cela utilise la compréhension de liste et que tout le monde peut le rechercher, s'il ne le sait pas.
xuiqzy

10

Encore une autre réponse:

-1... nécessite une importation
+1... est très lisible

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

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

sorties [10, 22, 36, 52]


Si vous connaissez la carte, c'est une solution vraiment lisible! L'importation a-t-elle des conséquences négatives à part être là en haut du fichier? (les éditeurs peuvent masquer les importations s'ils le souhaitent) Pour autant que je sache, il devrait être disponible dans toutes les versions de python 2 et 3!
xuiqzy

9

Façon assez intuitive de faire cela:

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

vous pouvez multiplier en utilisant lambda

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

4

Pour les grandes listes, nous pouvons le faire de manière itérative:

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

product_iter_object.next() donne chacun des éléments de la liste de sortie.

La sortie serait la longueur de la plus courte des deux listes d'entrée.


4

créer un tableau de ceux; multipliez chaque liste par le tableau; convertir un tableau en liste

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 réponse de gahooa est correcte pour la question telle que formulée dans l'en-tête, mais si les listes sont déjà au format numpy ou supérieures à dix, elles seront BEAUCOUP plus rapides (3 ordres de grandeur) et plus lisibles, pour faire une simple multiplication numpy comme suggéré par NPE. Je reçois ces horaires:

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

c'est-à-dire à partir du programme de test suivant.

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

Peut utiliser enumerate.

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

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

3

La mapfonction peut être très utile ici. En utilisant, mapnous pouvons appliquer n'importe quelle fonction à chaque élément d'un itérable.

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

Bien sûr:

map(f, iterable)

est équivalent à

[f(x) for x in iterable]

Nous pouvons donc obtenir notre solution via:

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

En Python 2.x map()signifie: appliquer une fonction à chaque élément d'un itérable et construire une nouvelle liste. Dans Python 3.x, mapconstruisez des itérateurs au lieu de listes.

Au lieu de my_mulnous pourrions utiliser l' mulopérateur

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

Veuillez noter que puisque map()construit un itérateur, nous utilisons l' *opérateur de décompression itérable pour obtenir une liste. L'approche de déballage est un peu plus rapide que le listconstructeur:

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

1

Pour conserver le type de liste et le faire en une seule ligne (après avoir importé numpy en tant que np, bien sûr):

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

ou

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

0

vous pouvez l'utiliser pour des listes de même longueur

def lstsum(a, b):
    c=0
    pos = 0
for element in a:
   c+= element*b[pos]
   pos+=1
return c
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.