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.


¿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.


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)

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)

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

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ó.


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

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

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

4

Esta pregunta ha sido respondida aquí

a = [1,2,3,4] sum (a) devuelve 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

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]

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


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

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]

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.


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

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

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

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


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

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

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

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

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.


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


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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.