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)) =).

xxjjnn
la source
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)]
gahooa
la source
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])
NPE
la source
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)
Brisa
la source
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))]
Nate
la source
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]

Petr Vepřek
la source
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
Col roulé
la source
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)
Benjamin
la source
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.

aady
la source
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]
litepresence
la source
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))
paddyg
la source
3

Peut utiliser enumerate.

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

ab = [val * b[i] for i, val in enumerate(a)]
SuperNova
la source
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]
>>>
sg7
la source
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))
puissant
la source
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
WOX GAMER
la source