Additionner une liste de nombres en Python


367

J'ai une liste de nombres tels que [1,2,3,4,5...], et je veux calculer (1+2)/2et pour le deuxième, (2+3)/2et le troisième (3+4)/2, et ainsi de suite. Comment puis je faire ça?

Je voudrais additionner le premier nombre avec le second et le diviser par 2, puis additionner le deuxième avec le troisième et diviser par 2, et ainsi de suite.

Aussi, comment puis-je additionner une liste de nombres?

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

Est-ce:

b = sum(a)
print b

obtenir un numéro?

Ça ne marche pas pour moi.


Quelle est la longueur de cette liste? quelle est la valeur aléatoire entre 0 et 1?
kevpie

2
si vous définissez sum avant qu'il ne puisse gâcher python, essayez del sum. il a peut-être été défini quelque part dans le code et remplace la fonction par défaut. Je l'ai donc supprimé et le problème a été résolu. (réponse de l'utilisateur4183543)
NicoKowe

1
"Cela ne fonctionne pas" n'est pas une description du problème.
Marquis de Lorne

Réponses:


279

Question 1: Vous voulez donc (élément 0 + élément 1) / 2, (élément 1 + élément 2) / 2, ... etc.

Nous faisons deux listes: une de chaque élément sauf le premier, et une de chaque élément sauf le dernier. Ensuite, les moyennes que nous voulons sont les moyennes de chaque paire tirées des deux listes. Nous utilisons zippour prendre des paires de deux listes.

Je suppose que vous voulez voir des décimales dans le résultat, même si vos valeurs d'entrée sont des entiers. Par défaut, Python fait une division entière: il rejette le reste. Pour diviser complètement les choses, nous devons utiliser des nombres à virgule flottante. Heureusement, la division d'un entier par un flottant produira un flottant, nous utilisons donc simplement 2.0notre diviseur au lieu de 2.

Donc:

averages = [(x + y) / 2.0 for (x, y) in zip(my_list[:-1], my_list[1:])]

Question 2:

Cette utilisation de sumdevrait fonctionner correctement. Les oeuvres suivantes:

a = range(10)
# [0,1,2,3,4,5,6,7,8,9]
b = sum(a)
print b
# Prints 45

De plus, vous n'avez pas besoin de tout affecter à une variable à chaque étape du processus. print sum(a)fonctionne très bien.

Vous devrez être plus précis sur exactement ce que vous avez écrit et comment cela ne fonctionne pas.


je n'ai pas eu, pour la première question j'ai obtenu la liste my_list non définie. Dans mon programme, c'est un nombre aléatoire pas 1, 2, 3, 4 .. pour la deuxième question, je ne travaille pas avec moi, je ne sais pas pourquoi
layo

37
my_listn'est défini que si vous le définissez. C'était censé être un espace réservé pour tout ce que vous appelez la liste avec laquelle vous essayez de travailler. Je ne peux pas deviner comment tu l'as appelé.
Karl Knechtel

2
6 ans plus tard, ce poste aide toujours les gens. J'ai eu un petit problème dans mon code et j'ai pu utiliser votre message pour confirmer que les concepts associés dans mon code au vôtre étaient également corrects, donc le problème doit se trouver ailleurs. Puis je l'ai trouvé. Je viens de vous donner, ainsi qu'à la personne qui a posé la question, un vote positif pour vous remercier rapidement. Meilleurs vœux.
TMWP

1
@KarlKnechtel Il avait une liste dans sa question et elle s'appelait " a".
HelloGoodbye

1
Puisque zips'arrête une fois qu'il atteint la fin de l'argument le plus court, cela zip(my_list, my_list[1:])suffit.
chepner

115

Liste des nombres:

sum(list_of_nums)

Calcul de la moitié de n et n - 1 (si j'ai le modèle correct), en utilisant une compréhension de liste :

[(x + (x - 1)) / 2 for x in list_of_nums]

Additionner les éléments adjacents, par exemple ((1 + 2) / 2) + ((2 + 3) / 2) + ... en utilisant réduire et lambdas

reduce(lambda x, y: (x + y) / 2, list_of_nums)

4
Je pense qu'il veut résumer les éléments adjacents. Il serait inutile de prendre la moyenne de xet x - 1; nous pourrions simplement soustraire 0,5 à la place.
Karl Knechtel

4
La fonction de réduction ne fait pas ce que dit le message. Il calcule (((a1 + a2) / 2 + a3) / 2 + a4) / 2 ...
Moberg

from functools import reduce
Tyrex

70

Question 2: Pour résumer une liste d'entiers:

a = [2, 3, 5, 8]
sum(a)
# 18
# or you can do:
sum(i for i in a)
# 18

Si la liste contient des entiers sous forme de chaînes:

a = ['5', '6']
# import Decimal: from decimal import Decimal
sum(Decimal(i) for i in a)

4
sum(i for i in a)est tout simplement redondant.
Jean-François Fabre

6
sum(Decimal(i) for i in a)=> sum(int(i) for i in a)ousum(map(int,a))
Jean-François Fabre

34

Vous pouvez essayer de cette façon:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sm = sum(a[0:len(a)]) # Sum of 'a' from 0 index to 9 index. sum(a) == sum(a[0:len(a)]
print(sm) # Python 3
print sm  # Python 2

4
pas besoin de créer une copie comme celle-ci, et c'est horriblement antipythonique. A éviter comme la peste malgré tous les votes ...
Jean-François Fabre

@ Jean-FrançoisFabre pourriez-vous s'il vous plaît détailler votre commentaire? Pourquoi est-ce "horriblement impythonique"?
PierreF

pour commencer, a[0:len(a)]crée une copie de a, quel est le point à part le gaspillage de CPU et de mémoire? puis print(sm)travaille également en python 2. Je ne comprends pas pourquoi cela a tant de upvotes à la mi-2017 ... mais il applique à la plupart des réponses ici.
Jean-François Fabre

27
>>> a = range(10)
>>> sum(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> del sum
>>> sum(a)
45

Il semble que cela sumait été défini quelque part dans le code et écrase la fonction par défaut. Je l'ai donc supprimé et le problème a été résolu.


16

En utilisant un simple list-comprehensionet le sum:

>> sum(i for i in range(x))/2. #if x = 10 the result will be 22.5

4
Vous n'avez pas besoin d'utiliser [et ], vous pouvez simplement passer l'expression du générateursum(i/2. for i in range(x))
Ivan

1
sum(range(x)) / 2.évite toutes les divisions, il suffit de diviser à la fin.
Jean-François Fabre

13

Toutes les réponses ont montré une approche programmatique et générale. Je propose une approche mathématique spécifique à votre cas. Cela peut être plus rapide en particulier pour les longues listes. Cela fonctionne parce que votre liste est une liste de nombres naturels jusqu'à n:

Supposons que nous ayons les nombres naturels 1, 2, 3, ..., 10:

>>> nat_seq = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Vous pouvez utiliser la sumfonction sur une liste:

>>> print sum(nat_seq)
55

Vous pouvez également utiliser la formule n*(n+1)/2nest la valeur du dernier élément de la liste (ici nat_seq[-1]:), afin d'éviter d'itérer sur les éléments:

>>> print (nat_seq[-1]*(nat_seq[-1]+1))/2
55

Pour générer la séquence, (1+2)/2, (2+3)/2, ..., (9+10)/2vous pouvez utiliser un générateur et la formule (2*k-1)/2.(notez le point pour faire flotter les valeurs). Vous devez ignorer le premier élément lors de la génération de la nouvelle liste:

>>> new_seq = [(2*k-1)/2. for k in nat_seq[1:]]
>>> print new_seq
[1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]

Ici aussi, vous pouvez utiliser la sumfonction sur cette liste:

>>> print sum(new_seq)
49.5

Mais vous pouvez également utiliser la formule (((n*2+1)/2)**2-1)/2pour éviter d'itérer sur les éléments:

>>> print (((new_seq[-1]*2+1)/2)**2-1)/2
49.5

6

La façon la plus simple de résoudre ce problème:

l =[1,2,3,4,5]
sum=0
for element in l:
    sum+=element
print sum

4

Cette question a été répondue ici

a = [1,2,3,4] sum (a) renvoie 10


3
import numpy as np    
x = [1,2,3,4,5]
[(np.mean((x[i],x[i+1]))) for i in range(len(x)-1)]
# [1.5, 2.5, 3.5, 4.5]

3

Les générateurs sont un moyen simple d'écrire ceci:

from __future__ import division
# ^- so that 3/2 is 1.5 not 1

def averages( lst ):
    it = iter(lst) # Get a iterator over the list
    first = next(it)
    for item in it:
        yield (first+item)/2
        first = item

print list(averages(range(1,11)))
# [1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5]

Vous pouvez également diviser par 2,0 pour éviter la division entière.
Chris Anderson

@ChrisAnderson n'est pas vrai en python 3. La division en virgule flottante est la valeur par défaut.
Justin Meiners

3

Rendons-le facile pour les débutants: -

  1. Le globalmot-clé permettra d'affecter le message de variable globale dans la fonction principale sans produire de nouvelle variable locale
    message = "This is a global!"


def main():
    global message
    message = "This is a local"
    print(message)


main()
# outputs "This is a local" - From the Function call
print(message)
# outputs "This is a local" - From the Outer scope

Ce concept est appelé l' observation

  1. Additionner une liste de nombres en Python
nums = [1, 2, 3, 4, 5]

var = 0


def sums():
    for num in nums:
        global var
        var = var + num
    print(var)


if __name__ == '__main__':
    sums()

Sorties = 15


2

Utilisation de la pairwise recette itertools :

import itertools
def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = itertools.tee(iterable)
    next(b, None)
    return itertools.izip(a, b)

def pair_averages(seq):
    return ( (a+b)/2 for a, b in pairwise(seq) )

2

Court et simple:

def ave(x,y):
  return (x + y) / 2.0

map(ave, a[:-1], a[1:])

Et voici à quoi ça ressemble:

>>> a = range(10)
>>> map(ave, a[:-1], a[1:])
[0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5]

En raison de la stupidité certaine dans la façon dont Python gère un mapsur deux listes, vous ne devez tronquer la liste, a[:-1]. Cela fonctionne mieux que ce à quoi vous vous attendez si vous utilisez itertools.imap:

>>> import itertools
>>> itertools.imap(ave, a, a[1:])
<itertools.imap object at 0x1005c3990>
>>> list(_)
[0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5]

Bref, oui. Facile? Il faut une explication plus longue que les longues solutions pour comprendre ce qu'il fait.
tekHedd

cela introduit une erreur d'accumulation en virgule flottante. Divisez à la fin à la place.
Jean-François Fabre

1
@ Jean-FrançoisFabre Les deux méthodes sont imparfaites - la division à la fin débordera pour les grands nombres, la solution dépend des données (et du cas d'utilisation).
cz

2

Tant de solutions, mais mon préféré manque toujours:

>>> import numpy as np
>>> arr = np.array([1,2,3,4,5])

un tableau numpy n'est pas trop différent d'une liste (dans ce cas d'utilisation), sauf que vous pouvez traiter les tableaux comme des nombres:

>>> ( arr[:-1] + arr[1:] ) / 2.0
[ 1.5  2.5  3.5  4.5]

Terminé!

explication

Les indices fantaisistes signifient ceci: [1:]inclut tous les éléments de 1 à la fin (omettant ainsi l'élément 0), et [:-1]sont tous des éléments à l'exception du dernier:

>>> arr[:-1]
array([1, 2, 3, 4])
>>> arr[1:]
array([2, 3, 4, 5])

Donc, ajouter ces deux vous donne un tableau composé d'élémens (1 + 2), (2 + 3) et ainsi de suite. Non pas que je divise 2.0, pas 2parce que sinon Python pense que vous n'utilisez que des entiers et produit des résultats entiers arrondis.

avantage d'utiliser numpy

Numpy peut être beaucoup plus rapide que les boucles autour des listes de nombres. Selon la taille de votre liste, plusieurs ordres de grandeur plus rapidement. De plus, c'est beaucoup moins de code, et au moins pour moi, c'est plus facile à lire. J'essaie de prendre l'habitude d'utiliser numpy pour tous les groupes de nombres, et c'est une énorme amélioration pour toutes les boucles et lops-within-loops que j'aurais autrement dû faire.


1

Je voudrais juste utiliser un lambda avec map ()

a = [1,2,3,4,5,6,7,8,9,10]
b = map(lambda x, y: (x+y)/2.0, fib[:-1], fib[1:])
print b

1

J'utilise une whileboucle pour obtenir le résultat:

i = 0
while i < len(a)-1:
   result = (a[i]+a[i+1])/2
   print result
   i +=1

1

Parcourez les éléments de la liste et mettez à jour le total comme ceci:

def sum(a):
    total = 0
    index = 0
    while index < len(a):
        total = total + a[index]
        index = index + 1
    return total

1

Grâce à Karl Knechtel, j'ai pu comprendre votre question. Mon interprétation:

  1. Vous souhaitez une nouvelle liste avec la moyenne des éléments i et i + 1.
  2. Vous voulez additionner chaque élément de la liste.

Première question en utilisant la fonction anonyme (aka. Fonction Lambda):

s = lambda l: [(l[0]+l[1])/2.] + s(l[1:]) if len(l)>1 else []  #assuming you want result as float
s = lambda l: [(l[0]+l[1])//2] + s(l[1:]) if len(l)>1 else []  #assuming you want floor result

Deuxième question utilisant également la fonction anonyme (aka. Fonction Lambda):

p = lambda l: l[0] + p(l[1:]) if l!=[] else 0

Les deux questions combinées dans une seule ligne de code:

s = lambda l: (l[0]+l[1])/2. + s(l[1:]) if len(l)>1 else 0  #assuming you want result as float
s = lambda l: (l[0]+l[1])/2. + s(l[1:]) if len(l)>1 else 0  #assuming you want floor result

utilisez celui qui correspond le mieux à vos besoins


1

Vous pouvez également faire de même en utilisant la récursivité:

Extrait Python:

def sumOfArray(arr, startIndex):
    size = len(arr)
    if size == startIndex:  # To Check empty list
        return 0
    elif startIndex == (size - 1): # To Check Last Value
        return arr[startIndex]
    else:
        return arr[startIndex] + sumOfArray(arr, startIndex + 1)


print(sumOfArray([1,2,3,4,5], 0))

0

Essayez d'utiliser une compréhension de liste. Quelque chose comme:

new_list = [(old_list[i] + old_list[i+1])/2 for i in range(len(old_list-1))]

@Rafe est fonctionnel (si nous fixons simplement les parenthèses à la fin - devrait l'être range(len(old_list) - 1)), mais les Pythonistas désapprouvent généralement la combinaison de 'range' et 'len'. Un corollaire à «il ne devrait y avoir qu'une seule façon de le faire» est «la bibliothèque standard vous permet d'éviter les choses laides». L'itération indirecte - itérer sur une séquence de nombres, afin que vous puissiez utiliser ces nombres pour indexer ce que vous voulez vraiment répéter - est une chose laide.
Karl Knechtel

0

Dans l'esprit d'itertools. Inspiration de la recette par paire.

from itertools import tee, izip

def average(iterable):
    "s -> (s0,s1)/2.0, (s1,s2)/2.0, ..."
    a, b = tee(iterable)
    next(b, None)
    return ((x+y)/2.0 for x, y in izip(a, b))

Exemples:

>>>list(average([1,2,3,4,5]))
[1.5, 2.5, 3.5, 4.5]
>>>list(average([1,20,31,45,56,0,0]))
[10.5, 25.5, 38.0, 50.5, 28.0, 0.0]
>>>list(average(average([1,2,3,4,5])))
[2.0, 3.0, 4.0]

0
n = int(input("Enter the length of array: "))
list1 = []
for i in range(n):
    list1.append(int(input("Enter numbers: ")))
print("User inputs are", list1)

list2 = []
for j in range(0, n-1):
    list2.append((list1[j]+list1[j+1])/2)
print("result = ", list2)

0

Un moyen simple consiste à utiliser la permutation iter_tools

# If you are given a list

numList = [1,2,3,4,5,6,7]

# and you are asked to find the number of three sums that add to a particular number

target = 10
# How you could come up with the answer?

from itertools import permutations

good_permutations = []

for p in permutations(numList, 3):
    if sum(p) == target:
        good_permutations.append(p)

print(good_permutations)

Le résultat est:

[(1, 2, 7), (1, 3, 6), (1, 4, 5), (1, 5, 4), (1, 6, 3), (1, 7, 2), (2, 1, 7), (2, 3, 
5), (2, 5, 3), (2, 7, 1), (3, 1, 6), (3, 2, 5), (3, 5, 2), (3, 6, 1), (4, 1, 5), (4, 
5, 1), (5, 1, 4), (5, 2, 3), (5, 3, 2), (5, 4, 1), (6, 1, 3), (6, 3, 1), (7, 1, 2), 
(7, 2, 1)]

Notez que l'ordre est important - ce qui signifie que 1, 2, 7 est également affiché comme 2, 1, 7 et 7, 1, 2. Vous pouvez réduire cela en utilisant un ensemble.


0

Dans Python 3.8, le nouvel opérateur d'affectation peut être utilisé

>>> my_list = [1, 2, 3, 4, 5]
>>> itr = iter(my_list)
>>> a = next(itr)
>>> [(a + (a:=x))/2 for x in itr]
[1.5, 2.5, 3.5, 4.5]

aest une référence courante à la valeur précédente de la liste, par conséquent, elle est initialisée au premier élément de la liste et l'itération se produit sur le reste de la liste, en mettant à joura à après son utilisation à chaque itération.

Un itérateur explicite est utilisé pour éviter d'avoir à créer une copie de la liste à l'aide de my_list[1:].


-3

Essayez ce qui suit -

mylist = [1, 2, 3, 4]   

def add(mylist):
    total = 0
    for i in mylist:
        total += i
    return total

result = add(mylist)
print("sum = ", result)

2
Une nouvelle réponse devrait vraiment être distinctement différente des réponses existantes. En outre, votre sumfonction ne diffère pas du sumcomportement ou du nom intégré . Vous pouvez réellement supprimer la définition de fonction de votre réponse et cela fonctionnerait toujours.
Noumenon

pouvez-vous s'il vous plaît vérifier maintenant
Sai G

2
J'apprécie que vous amélioriez votre réponse! Les noms de variables sont plus descriptifs et n'obscurcissent pas les fonctions intégrées. Mais les problèmes fondamentaux sont toujours là: l'approche for-loop a déjà été fournie par stackoverflow.com/a/35359188/733092 ci-dessus, et la fonction est redondante avec le intégré sum. Vous obtiendrez un A sur un test pour répondre correctement à la question, mais les réponses StackOverflow doivent également être utiles aux personnes arrivant sur cette page, et les réponses en double ne le sont pas.
Noumenon
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.