Comment additionner la première valeur de chaque tuple dans une liste de n-uplets en Python?
Question
J'ai une liste de n-uplets (toujours des paires) comme ceci:
[(0, 1), (2, 3), (5, 7), (2, 1)]
J'aimerais trouver la somme des premiers éléments de chaque paire, c'est-à-dire:
0 + 2 + 5 + 2
Comment puis-je faire cela en Python? En ce moment, je parcours la liste:
sum = 0
for pair in list_of_pairs:
sum += pair[0]
J'ai le sentiment qu'il doit y avoir une manière plus pythonique.
La solution
Une version compatible avec Python 2.3 est
sum([pair[0] for pair in list_of_pairs])
ou dans les versions récentes de Python, voir cette réponse ou celui-ci .
Autres conseils
sum(i for i, j in list_of_pairs)
le fera aussi.
Je recommande:
sum(i for i, _ in list_of_pairs)
Remarque :
Utilisation de la variable _
(ou __
pour éviter les conflits avec l'alias de gettext
) au lieu de j
présente au moins deux avantages:
-
_
(qui signifie espace réservé) a une meilleure lisibilité -
pylint
ne se plaindra pas: "Variable 'j' non utilisée" "
Si vous avez une très grande liste ou un générateur qui produit un grand nombre de paires, vous pouvez utiliser une approche basée sur un générateur. Pour le plaisir, j'utilise aussi itemgetter ()
et imap ()
. Une approche simple basée sur un générateur pourrait toutefois suffire.
import operator
import itertools
idx0 = operator.itemgetter(0)
list_of_pairs = [(0, 1), (2, 3), (5, 7), (2, 1)]
sum(itertools.imap(idx0, list_of_pairs))
Notez que itertools.imap ()
est disponible en Python > = 2.3. Vous pouvez donc également utiliser une approche basée sur un générateur.
Réponse obscure (mais amusante):
>>> sum(zip(*list_of_pairs)[0])
9
Ou, lorsque les zip sont des itérables, seul cela devrait fonctionner:
>>> sum(zip(*list_of_pairs).__next__())
9
Ci-dessous un exemple de code, vous pouvez également spécifier la plage de la liste.
def test_lst_sum():
lst = [1, 3, 5]
print sum(lst) # 9
print sum(lst[1:]) # 8
print sum(lst[5:]) # 0 out of range so return 0
print sum(lst[5:-1]) # 0
print sum(lst[1: -1]) # 3
lst_tp = [('33', 1), ('88', 2), ('22', 3), ('44', 4)]
print sum(x[1] for x in lst_tp[1:]) # 9
Si cela ne vous dérange pas de le convertir en tableau numpy, vous pouvez utiliser np.sum
sur axis = 0
comme indiqué ici