简体   繁体   中英

how can i put for loop for this given list?

I code is given below I couldn't make it for loop. In this code totd_list is list of some random numbers. I want to average of index number 1, then average of next two indices, then average of next three indices and then average of next 4 indices. How can I put a put for loop for to gain more decent results?

avg[0]=totd_list[0]
avg[1]=(totd_list[1]+totd_list[2])/2
avg[2]=(totd_list[3]+totd_list[4]+totd_list[5])/3
avg[3]=(totd_list[6]+totd_list[7]+totd_list[8]+totd_list[9])/4
avg[4]=(totd_list[10]+totd_list[11]+totd_list[12]+totd_list[13]+totd_list[14])/5

That can be done with a comprehension, but it is a bit convoluted:

Code:

totd_list = [2] * 15
an_iter = iter(totd_list)

sums = [sum((next(an_iter) for j in range(i+1))) for i in range(5)]
print(sums)

avg = [s / (i+1) for i, s in enumerate(sums)]
print(avg)

Results:

[2, 4, 6, 8, 10]
[2, 2, 2, 2, 2]

First, we know that the we're probably going to be incrementing the index of avg on each iteration of our loop, right? So let's suppose our index is called idx . The, if we continue to try and find the pattern, we see that we always average idx+1 many elements of our list, starting from some point, call it j . In other words,

avg[idx] = (totd_list[j] + ... + totd_list[j+idx]) / (idx+1)

So now we have to work out what j is. We have two options. The easiest would be to just have a variable called j and increment it by idx + 1 at the end of each iteration. The other would be to notice that the above means j=1+2+...+idx . There's a well-known formula for that sort of sum (and a fun story about Gauss)--it's idx*(idx+1)/2 .

There are two pieces left:

  • making sure we stop and start our loop in the right places (well, idx definitely starts at 0 )
  • actually summing an arbitrary slice of a list

The second is easy. If l is a list l[a:b] is l[a], l[a+1],..., l[b-1] , so we can just sum(l[j:j+idx+1]) .

The first is a little harder. You could either use a while loop and check that idx + j is less than the length of the list (ie you have enough elements left), or you could work out how many elements are consumed at each iteration (remember, we know this, it's idx ) and use the Gauss formula to work out how many iterations you can make. You'll have to decide what to do when you have "extra" elements left.

I'll leave actually writing the code to you.

You could use the triangle numbers here, since your loop seems to want to slice [0:1] , [1:3] , [3:6] , [6:10] , [ 10:15] . The end of these slices match the triangle numbers 1, 3, 6, 10, 15. You can also visit Triangular number for more information on this pattern.

This will allow the following slices to be generated for the list [i for i in range(15)] :

[0]
[1, 2]
[3, 4, 5]
[6, 7, 8, 9]
[10, 11, 12, 13, 14]

You can then use the above logic to compute your averages:

lst = [i for i in range(15)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

# hard coded value, adapt it to something else
n = 5

avg = []

start = 0

# Loop n iterations
for i in range(1, n + 1):

   # Get the triangle number
    end = (i ** 2 + i) // 2

    # Slice your list
    seq = lst[start:end]

    # Compute average and add it to list
    avg.append(sum(seq)/i)

    # Reset start index to end
    start = end

print(avg)

Where gives the following averages in a list:

[0.0, 1.5, 4.0, 7.5, 12.0]

Note: You will need to tweak the above for your needs, but it should give the general idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM