Python, how to calculate the average of a list of 5 in 5 elements?

Asked

Viewed 197 times

0

I have a problem where I need to calculate the average of 5 out of 5 elements in a list, for example, average the first 5 elements, then average the next 5 elements and so on. I tried using list slices [::5] but this only returns the interval and is not what I want. I will leave here a small code as an example:

lista = [1,2,4,3,7,4,6,5,8,1,9,4,3] # Aqui seria calcular a média do 1 até o 7 depois do 4 até o 1 e assim em diante...     
media = sum(lista[::5]) / 5     
print(media)       

4 answers

4

The session "Itertools Recipes" in module documentation itertools contains an example of a function called grouper which makes the grouping of N into N elements of an iterable (efficiently). Just you calculate the average of each returned group of that function.

Follow an example using the documentation example:

from itertools import zip_longest

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)


lista = [1, 2, 4, 3, 7, 4, 6, 5, 8, 1, 9, 4, 3]

for grupo in grouper(lista, n=5):
    # Remove os `None` do último grupo
    grupo = [num for num in grupo if num is not None]

    media = sum(grupo) / len(grupo)

    print(f"Grupo: {grupo!r}")
    print(f"- Média: {media}")

Exit:

Grupo: [1, 2, 4, 3, 7]
- Média: 3.4
Grupo: [4, 6, 5, 8, 1]
- Média: 4.8
Grupo: [9, 4, 3]
- Média: 5.333333333333333

Edit

I’m using list comprehension along with is not Noneto remove the values None from the last group, because if I just test if the number is falsifiable the code would remove the zeros from the list.

lista = [0, 1, 2, 3, None]

ok = [n for n in lista if n is not None]  # [0, 1, 2, 3]
wrong = [n for n in lista if n]  # [1, 2, 3]
wrong_too = list(filter(None, lista))  # [1, 2, 3]

3

One possibility is to create a generator splitting an iterable into portions and calculating individually the averages for these portions.

lista = [1,2,4,3,7,4,6,5,8,1,9,4,3]

def chunk(iteravel, n):
    for i in range(0, len(iteravel), n):
        yield iteravel[i:i+n]

s = map(lambda e:sum(e)/len(e), chunk(lista, 5))


print(*s)    #3.4 4.8 5.333333333333333

Test the code on ideone.

3

  1. One is up to the list size with step 5

  2. in the second to complete the list of five elements (list5)

  3. Calculate the sum of the list5 and divide by the size to get the average.

     lista = [1,2,4,3,7,4,6,5,8,1,9,4,3]
     media = []
     for i in range(0, len(lista), 5):
         lista5 = []
         for j in range(0, 5):
             if((i + j) < len(lista)):
                 lista5.append(lista[i + j])
                 print(str(lista[i + j]), end=' ')
         media.append(sum(lista5) / len(lista5))
         print()
     print(media)
    

2

A solution with list comprehension:

lista = [1,2,4,3,7,4,6,5,8,1,9,4,3] 
r = 5
media = [sum(lista[i:i+r])/len(lista[i:i+r]) for i in range(0,len(lista),r)]
print(media)

As mentioned @fernandosavio, we can use the operator Walrus, but works with python 3.8 and higher:

media = [sum(l:=lista[i:i+r])/len(l) for i in range(0,len(lista),r)]

Exit:

[3.4, 4.8, 5.333333333333333]
  • The average of the last group should be 5.3333... because the last grouping has only 3 elements and not 5

  • 1

    But you can solve using Walrus Operator: [sum(l:=lista[i:i+r])/len(l) for i in range(0,len(lista),r)]. I’ll leave the docs for the curious

  • @fernandosavio, Thank you, updated!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.