J'ai maintenant:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
Je souhaite avoir:
[1, 2, 3]
+ + +
[4, 5, 6]
|| || ||
[5, 7, 9]
Simplement un ajout élémentaire de deux listes.
Je peux sûrement parcourir les deux listes, mais je ne veux pas le faire.
Quelle est la manière la plus pythonique de le faire?
Utilisez map
avec operator.add
:
_>>> from operator import add
>>> list( map(add, list1, list2) )
[5, 7, 9]
_
ou Zip
avec une liste de compréhension:
_>>> [sum(x) for x in Zip(list1, list2)]
[5, 7, 9]
_
_>>> list2 = [4, 5, 6]*10**5
>>> list1 = [1, 2, 3]*10**5
>>> %timeit from operator import add;map(add, list1, list2)
10 loops, best of 3: 44.6 ms per loop
>>> %timeit from itertools import izip; [a + b for a, b in izip(list1, list2)]
10 loops, best of 3: 71 ms per loop
>>> %timeit [a + b for a, b in Zip(list1, list2)]
10 loops, best of 3: 112 ms per loop
>>> %timeit from itertools import izip;[sum(x) for x in izip(list1, list2)]
1 loops, best of 3: 139 ms per loop
>>> %timeit [sum(x) for x in Zip(list1, list2)]
1 loops, best of 3: 177 ms per loop
_
Les autres ont donné des exemples sur la manière de faire cela en python pur. Si vous voulez faire cela avec des tableaux avec 100.000 éléments, vous devriez utiliser numpy:
In [1]: import numpy as np
In [2]: vector1 = np.array([1, 2, 3])
In [3]: vector2 = np.array([4, 5, 6])
Faire l’addition élément par élément est maintenant aussi trivial que
In [4]: sum_vector = vector1 + vector2
In [5]: print sum_vector
[5 7 9]
comme dans Matlab.
Calendrier à comparer avec la version la plus rapide d'Ashwini:
In [16]: from operator import add
In [17]: n = 10**5
In [18]: vector2 = np.tile([4,5,6], n)
In [19]: vector1 = np.tile([1,2,3], n)
In [20]: list1 = [1,2,3]*n
In [21]: list2 = [4,5,6]*n
In [22]: timeit map(add, list1, list2)
10 loops, best of 3: 26.9 ms per loop
In [23]: timeit vector1 + vector2
1000 loops, best of 3: 1.06 ms per loop
C'est donc un facteur 25 plus rapide! Mais utilisez ce qui convient à votre situation. Pour un programme simple, vous ne voulez probablement pas installer numpy, utilisez donc la norme python (et je trouve que la version de Henry est la plus pythonique). Si vous êtes sérieux dans le calcul, laissez numpy
faire le gros du travail. Pour les amateurs de vitesse: il semble que la solution numpy soit plus rapide à partir de n = 8
.
[a + b for a, b in Zip(list1, list2)]
Comme décrit par d’autres, une solution rapide et peu encombrante utilise numpy (np) avec sa capacité intégrée de manipulation de vecteurs:
1. Avec Numpy
x = np.array([1,2,3])
y = np.array([2,3,4])
print x+y
2. Avec éléments intégrés
2.1 Lambda
list1=[1, 2, 3]
list2=[4, 5, 6]
print map(lambda x,y:x+y, list1, list2)
Notez que map () supporte plusieurs arguments.
2.2 Zip et compréhension de la liste
list1=[1, 2, 3]
list2=[4, 5, 6]
print [x + y for x, y in Zip(list1, list2)]
Il est plus simple d'utiliser numpy
de mon point de vue:
import numpy as np
list1=[1,2,3]
list2=[4,5,6]
np.add(list1,list2)
Résultats:
Pour des informations détaillées sur les paramètres, vérifiez ici: numpy.add
C'est simple avec numpy.add()
import numpy
list1 = numpy.array([1, 2, 3])
list2 = numpy.array([4, 5, 6])
result = numpy.add(list1, list2) # result receive element-wise addition of list1 and list2
print(result)
array([5, 7, 9])
Si vous souhaitez recevoir une liste python:
result.tolist()
Peut-être que "la manière la plus pythonique" devrait inclure la gestion du cas où list1 et list2 ne sont pas de la même taille. L'application de certaines de ces méthodes vous donnera tranquillement une réponse. L’approche numpy vous le fera savoir, très probablement avec ValueError.
Exemple:
import numpy as np
>>> list1 = [ 1, 2 ]
>>> list2 = [ 1, 2, 3]
>>> list3 = [ 1 ]
>>> [a + b for a, b in Zip(list1, list2)]
[2, 4]
>>> [a + b for a, b in Zip(list1, list3)]
[2]
>>> a = np.array (list1)
>>> b = np.array (list2)
>>> a+b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (2) (3)
Quel résultat voudriez-vous si cela faisait partie de votre problème?
Cela fonctionnera pour 2 listes ou plus; parcourir la liste des listes, mais utiliser numpy addition pour traiter les éléments de chaque liste
import numpy as np
list1=[1, 2, 3]
list2=[4, 5, 6]
lists = [list1, list2]
list_sum = np.zeros(len(list1))
for i in lists:
list_sum += i
list_sum = list_sum.tolist()
[5.0, 7.0, 9.0]
Peut-être que c'est Pythonic et légèrement utile si vous avez un nombre inconnu de listes et sans rien importer.
Tant que les listes ont la même longueur, vous pouvez utiliser la fonction ci-dessous.
Ici, l'argument * accepte un nombre variable d'arguments de liste (mais ajoute seulement le même nombre d'éléments dans chacun).
Le * est à nouveau utilisé dans la liste renvoyée pour décompresser les éléments de chacune des listes.
def sum_lists(*args):
return list(map(sum, Zip(*args)))
a = [1,2,3]
b = [1,2,3]
sum_lists(a,b)
Sortie:
[2, 4, 6]
Ou avec 3 listes
sum_lists([5,5,5,5,5], [10,10,10,10,10], [4,4,4,4,4])
Sortie:
[19, 19, 19, 19, 19]
Je ne l'ai pas chronométré mais je suppose que cela serait assez rapide:
import numpy as np
list1=[1, 2, 3]
list2=[4, 5, 6]
list_sum = (np.add(list1, list2)).tolist()
[5, 7, 9]
Utilisez la carte avec la fonction lambda:
>>> map(lambda x, y: x + y, list1, list2)
[5, 7, 9]
Si vous avez besoin de gérer des listes de tailles différentes, ne vous inquiétez pas! Le merveilleux module itertools vous a couvert:
_>>> from itertools import Zip_longest
>>> list1 = [1,2,1]
>>> list2 = [2,1,2,3]
>>> [sum(x) for x in Zip_longest(list1, list2, fillvalue=0)]
[3, 3, 3, 3]
>>>
_
Dans Python 2, _Zip_longest
_ est appelé izip_longest
.
Voir aussi cette réponse pertinente et commenter une autre question .
Bien que la question ne veuille pas parcourir la liste pour générer le résultat, toutes les solutions proposées font exactement cela sous le capot!
Pour actualiser: Vous ne pouvez pas ajouter deux vecteurs sans examiner tous les éléments vectoriels. La complexité algorithmique de la plupart de ces solutions est donc Big-O (n). Où n est la dimension du vecteur.
Donc, d’un point de vue algorithmique, utiliser une boucle for pour générer de manière itérative la liste résultante est logique et Pythonic aussi. Toutefois, en outre, cette méthode ne nécessite pas l’appel ou l’importation d’une bibliothèque supplémentaire.
# Assumption: The lists are of equal length.
resultList = [list1[i] + list2[i] for i in range(len(list1))]
Les délais présentés/discutés ici dépendent du système et de la mise en œuvre et ne peuvent constituer une mesure fiable pour mesurer l'efficacité de l'opération. Dans tous les cas, la grande complexité en O de l'opération d'addition de vecteur est linéaire, ce qui signifie O (n).
[list1[i] + list2[i] for i in range(len(list1))]
a_list = []
b_list = []
for i in range(1,100):
a_list.append(random.randint(1,100))
for i in range(1,100):
a_list.append(random.randint(101,200))
[sum(x) for x in Zip(a_list , b_list )]