Suma una lista de números en Python

367

Tengo una lista de números como [1,2,3,4,5...], y quiero calcular (1+2)/2y para el segundo, (2+3)/2y el tercero (3+4)/2, y así sucesivamente. ¿Cómo puedo hacer eso?

Me gustaría sumar el primer número con el segundo y dividirlo por 2, luego sumar el segundo con el tercero y dividir por 2, y así sucesivamente.

Además, ¿cómo puedo sumar una lista de números?

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

Lo es:

b = sum(a)
print b

para obtener un número?

Esto no funciona para mi.

layo
fuente
¿Cuánto dura esta lista? ¿Qué tan aleatorios son los valores, entre 0 y 1?
kevpie
2
si define sum antes de que pueda ensuciar Python, intente del sum. tal vez se ha definido en algún lugar del código y sobrescribe la función predeterminada. Así que lo eliminé y el problema se resolvió. (respuesta del usuario 4183543)
NicoKowe
1
"Esto no funciona" no es una descripción del problema.
Marqués de Lorne

Respuestas:

279

Pregunta 1: Entonces desea (elemento 0 + elemento 1) / 2, (elemento 1 + elemento 2) / 2, ... etc.

Hacemos dos listas: una de cada elemento, excepto el primero, y una de cada elemento, excepto el último. Entonces, los promedios que queremos son los promedios de cada par tomado de las dos listas. Usamoszip tomar pares de dos listas.

Supongo que desea ver decimales en el resultado, a pesar de que sus valores de entrada son enteros. Por defecto, Python realiza la división de enteros: descarta el resto. Para dividir las cosas por completo, necesitamos usar números de punto flotante. Afortunadamente, dividir un int por un float producirá un float, por lo que solo usamos 2.0para nuestro divisor en lugar de 2.

Así:

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

Pregunta 2:

Ese uso de sumdebería funcionar bien. Los siguientes trabajos:

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

Además, no necesita asignar todo a una variable en cada paso del camino. print sum(a)funciona bien

Tendrás que ser más específico sobre exactamente lo que escribiste y cómo no está funcionando.

Karl Knechtel
fuente
no obtuve, para la primera pregunta obtuve el my_list indefinido. En mi programa es un número aleatorio, no 1, 2, 3, 4 .. para la segunda pregunta no funciona conmigo, no sé por qué
layo
37
my_listsolo se define si lo define. Se suponía que era un marcador de posición para lo que llamaras la lista con la que intentas trabajar. No puedo adivinar cómo lo llamaste.
Karl Knechtel
2
6 años después, esta publicación sigue ayudando a las personas. Tuve un error en mi código y pude usar tu publicación para confirmar que los conceptos relacionados con mi código también eran correctos, por lo que el problema debe estar en otra parte. Entonces lo encontré. Solo les di a usted y a la persona con la pregunta un voto positivo como agradecimiento rápido. Los mejores deseos.
TMWP
1
@KarlKnechtel Tenía una lista en su pregunta y se llamaba " a".
Hola
1
Como se zipdetiene una vez que llega al final del argumento más corto, zip(my_list, my_list[1:])es suficiente.
chepner
115

Suma lista de números:

sum(list_of_nums)

Calculando la mitad de n y n - 1 (si tengo el patrón correcto), usando una lista de comprensión :

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

Suma elementos adyacentes, por ejemplo ((1 + 2) / 2) + ((2 + 3) / 2) + ... usando reduce y lambdas

reduce(lambda x, y: (x + y) / 2, list_of_nums)
Rafe Kettler
fuente
44
Creo que quiere sumar elementos adyacentes. No tendría sentido tomar el promedio de xy x - 1; podríamos restar 0.5 en su lugar.
Karl Knechtel
44
La función reducir no hace lo que dice la publicación. Calcula (((a1 + a2) / 2 + a3) / 2 + a4) / 2 ...
Moberg
from functools import reduce
tyrex
70

Pregunta 2: Para resumir una lista de enteros:

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

Si la lista contiene enteros como cadenas:

a = ['5', '6']
# import Decimal: from decimal import Decimal
sum(Decimal(i) for i in a)
Evans Murithi
fuente
44
sum(i for i in a)es redundante
Jean-François Fabre
66
sum(Decimal(i) for i in a)=> sum(int(i) for i in a)osum(map(int,a))
Jean-François Fabre
34

Puedes probar de esta manera:

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
Md. Rezwanul Haque
fuente
44
no es necesario crear una copia como esta, y es terriblemente antipático. Evita como la peste a pesar de todos los votos ...
Jean-François Fabre
@ Jean-FrançoisFabre, ¿podría detallar su comentario? ¿Por qué es esto "terriblemente antipático"?
PierreF
para empezar a[0:len(a)]crea una copia de a, ¿cuál es el punto además de desperdiciar CPU y memoria? luego print(sm)también funciona en python 2. No entiendo por qué esto tiene tantos votos a mediados de 2017 ... pero se aplica a la mayoría de las respuestas aquí.
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

Parece que sumse ha definido en algún lugar del código y sobrescribe la función predeterminada. Así que lo eliminé y el problema se resolvió.

usuario4183543
fuente
16

Usando un simple list-comprehensiony el sum:

>> sum(i for i in range(x))/2. #if x = 10 the result will be 22.5
AndreL
fuente
44
No necesita usar [y ], simplemente puede pasar la expresión del generadorsum(i/2. for i in range(x))
Ivan
1
sum(range(x)) / 2.evita todas las divisiones, solo divide al final.
Jean-François Fabre
13

Todas las respuestas mostraron un enfoque programático y general. Sugiero un enfoque matemático específico para su caso. Puede ser más rápido en particular para listas largas. Funciona porque su lista es una lista de números naturales hasta n:

Supongamos que tenemos los números naturales 1, 2, 3, ..., 10:

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

Puede usar la sumfunción en una lista:

>>> print sum(nat_seq)
55

También puede usar la fórmula n*(n+1)/2donde nestá el valor del último elemento de la lista (aquí nat_seq[-1]:), para evitar iterar sobre los elementos:

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

Para generar la secuencia (1+2)/2, (2+3)/2, ..., (9+10)/2, puede usar un generador y la fórmula (2*k-1)/2.(observe el punto para convertir los valores en puntos flotantes). Debe omitir el primer elemento al generar la nueva lista:

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

Aquí también, puede usar la sumfunción en esa lista:

>>> print sum(new_seq)
49.5

Pero también puede usar la fórmula (((n*2+1)/2)**2-1)/2, por lo que puede evitar iterar sobre los elementos:

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

La forma más sencilla de resolver este problema:

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

Esta pregunta ha sido respondida aquí

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

Vijay
fuente
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]
tagoma
fuente
3

Los generadores son una manera fácil de escribir esto:

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]
Jochen Ritzel
fuente
También puede dividir por 2.0 para evitar la división de enteros.
Chris Anderson
@ChrisAnderson no es cierto en Python 3. La división de punto flotante es el valor predeterminado.
Justin Meiners
3

Hagamos que sea fácil para principiantes: -

  1. La globalpalabra clave permitirá que se asigne el mensaje de variable global dentro de la función principal sin producir una nueva variable local
    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

Este concepto se llama Sombreado

  1. Suma una lista de números 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()

Salidas = 15

Aamir M Meman
fuente
2

Usando la pairwise receta 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) )
tzot
fuente
2

Corto y simple:

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

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

Y así es como se ve:

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

Debido a alguna estupidez en la forma en Python maneja una mapmás de dos listas, usted tiene que truncar la lista, a[:-1]. Funciona más de lo que cabría esperar si usa 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]
Michael J. Barber
fuente
Corto sí. ¿Simple? Requiere una explicación más larga que las largas soluciones para comprender lo que está haciendo.
tekHedd
Esto introduce un error de acumulación de coma flotante. Divide al final en su lugar.
Jean-François Fabre
1
@ Jean-FrançoisFabre Ambos métodos son imperfectos: dividir al final se desbordará para grandes números, la solución depende de los datos (y el caso de uso).
cz
2

Tantas soluciones, pero aún falta mi favorita:

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

una matriz numpy no es muy diferente de una lista (en este caso de uso), excepto que puede tratar las matrices como números:

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

¡Hecho!

explicación

Los índices elegantes significan esto: [1:]incluye todos los elementos desde 1 hasta el final (omitiendo así el elemento 0), y [:-1]son todos los elementos excepto el último:

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

Entonces, agregar esos dos le da una matriz que consta de elementos (1 + 2), (2 + 3) y así sucesivamente. No es que esté dividiendo por 2.0, no 2porque, de lo contrario, Python cree que solo está usando enteros y produce resultados enteros redondeados.

ventaja de usar numpy

Numpy puede ser mucho más rápido que los bucles alrededor de las listas de números. Dependiendo de cuán grande sea su lista, varios órdenes de magnitud más rápido. Además, es mucho menos código y, al menos para mí, es más fácil de leer. Estoy tratando de hacer un hábito el uso de numpy para todos los grupos de números, y es una gran mejora para todos los bucles y bucles dentro de bucles que de otro modo habría tenido que hacer.

Zak
fuente
1

Solo usaría una lambda con 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
Orane
fuente
1

Yo uso un whilebucle para obtener el resultado:

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

Recorra los elementos de la lista y actualice el total de esta manera:

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

Gracias a Karl Knechtel pude entender tu pregunta. Mi interpretación:

  1. Desea una nueva lista con el promedio del elemento i e i + 1.
  2. Desea sumar cada elemento en la lista.

Primera pregunta usando la función anónima (también conocida como función 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

Segunda pregunta que también usa la función anónima (también conocida como función Lambda):

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

Ambas preguntas se combinaron en una sola línea de código:

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

use el que mejor se adapte a sus necesidades

Stickysli
fuente
1

También puede hacer lo mismo usando recursividad:

Fragmento de 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))
vijayraj34
fuente
0

Intenta usar una lista de comprensión. Algo como:

new_list = [(old_list[i] + old_list[i+1])/2 for i in range(len(old_list-1))]
TartánLlama
fuente
@Rafe es funcional (si arreglamos los paréntesis al final, debería serlo range(len(old_list) - 1)), pero los Pythonistas generalmente desaprueban la combinación de 'rango' y 'len'. Un corolario de "solo debería haber una forma de hacerlo" es "la biblioteca estándar proporciona una manera de evitar cosas feas". La iteración indirecta - iterar sobre una secuencia de números, para que pueda usar esos números para indexar lo que realmente desea iterar - es algo feo.
Karl Knechtel
0

En el espíritu de itertools. Inspiración de la receta por parejas.

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

Ejemplos:

>>>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]
kevpie
fuente
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)
vasanth kumar
fuente
0

Una manera simple es usar la permutación 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)

El resultado es:

[(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)]

Tenga en cuenta que el orden es importante, es decir, 1, 2, 7 también se muestra como 2, 1, 7 y 7, 1, 2. Puede reducir esto utilizando un conjunto.

Jesse
fuente
0

En Python 3.8, se puede usar el nuevo operador de asignación

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

aes una referencia en ejecución al valor anterior en la lista, por lo tanto, se inicializa al primer elemento de la lista y la iteración se produce en el resto de la lista, actualizándose adespués de que se utiliza en cada iteración.

Se usa un iterador explícito para evitar la necesidad de crear una copia de la lista usando my_list[1:].

chepner
fuente
-3

Intenta lo siguiente:

mylist = [1, 2, 3, 4]   

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

result = add(mylist)
print("sum = ", result)
Sai G
fuente
2
Una nueva respuesta debería ser realmente diferente de las respuestas existentes. Además, su sumfunción no difiere del sumcomportamiento o nombre incorporado . En realidad, podría eliminar la definición de función de su respuesta y aún funcionaría.
Noumenon
¿Puedes comprobar ahora?
Sai G
2
¡Aprecio que estés mejorando tu respuesta! Los nombres de las variables son más descriptivos y no sombrean los incorporados. Pero los problemas fundamentales siguen ahí: el enfoque for-loop ya fue proporcionado por stackoverflow.com/a/35359188/733092 arriba, y la función es redundante con el incorporado sum. Obtendría una A en un examen por responder la pregunta correctamente, pero las respuestas de StackOverflow también deben ser útiles para las personas que llegan a esta página, y las respuestas duplicadas no lo son.
Noumenon