0

Hi Im super new to programming and I dont know how to write a loop which will expand an empty list with a sum of previous numbers in range(1, 21). So the list should look like this (1 , 1+2 , 1+2+3 etc)

Piotrek Wcisło
  • 85
  • 1
  • 10
  • @miradulo Nah, this is a special case, allowing special solutions. – Stefan Pochmann Nov 02 '17 at 17:10
  • @StefanPochmann Sorry can you elaborate? It seems like a clear duplicate to me unless you use partial sums given the sequence form, but that seems like a reach. – miradulo Nov 02 '17 at 17:46
  • @miradulo That other question is for the general case. Input can be any list. This one is for a special case. Sure, you can use the answers for that other question to solve this one, but *you don't have to*. The specialness might for example allow *simpler* answers. – Stefan Pochmann Nov 02 '17 at 18:13
  • @miradulo Not sure what you mean with "use partial sums given the sequence form", btw. – Stefan Pochmann Nov 02 '17 at 18:17
  • @StefanPochmann I disagree - that isn't the essence of this question IMHO unless OP further clarifies, but I can see where you're coming from. By partial sums of the sequence I meant you could use the fact that the i-th element in such a list will be i(i+1)/2 instead of doing a regular accumulating sum, but it will be slower anyways. Maybe there's something more clever though. – miradulo Nov 02 '17 at 18:20
  • @miradulo Yes, that's exactly one example. In fact, `[i*(i+1)//2 for i in range(1, 21)]` might be the shortest possible solution. But you won't find it under that other question. Because there it's not a valid solution. – Stefan Pochmann Nov 02 '17 at 18:26
  • @StefanPochmann Sure. If we're code golfing then how about `[i*-~i//2 for i in range(1, 21)]` ;). I don't know, agree to disagree I guess - just don't see how this question offers any value to anyone trying to solve a meaningful problem. – miradulo Nov 02 '17 at 18:33
  • @miradulo Yeah, I wasn't golfing, just wrote it the normal way. For golfing, you should also remove the two unneeded spaces :-). I just added an answer myself, btw, one that also exploits the specialness and can't be used for the other question. – Stefan Pochmann Nov 02 '17 at 18:37

5 Answers5

2
l = range(1, 21)
print ([sum(l[:i]) for i in l])
#Output:
#[1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210]

To make it generic to any list, here you go

l = [3,4,5,6,7,12] # or l = range(1, 21)
print ([sum(l[:i]) for i in range(1,len(l)+1)])
#Output:
#[3, 7, 12, 18, 25, 37]
Transhuman
  • 3,527
  • 1
  • 9
  • 15
  • This won't work if you change the lower bound on `l` or use a totally different list e.g. `l=[8,4,2]`. I suggest using `range` a second time: `[sum(l[:i+1]) for i in range(len(l))]` – Arthur Tacca Nov 02 '17 at 17:32
  • @Arthur Tacca - my solution is based on OP's input and expected output :) – Transhuman Nov 02 '17 at 17:34
  • Well OK, here's a another valid way of doing it: `result=[1, 3, 6, 10, ...` (you get the idea) :-) My comment gives the same result as your answer but IMO it is a bit clearer because it is not using the values in the list as indices into the same list. Even if it will never be used with a different lower bound, I find it a bit mind boggling. – Arthur Tacca Nov 02 '17 at 17:37
0
>>> MyList = []
>>> for i in range(1 + 1,21):
...   partial_sum = 0
...   for j in range(1,i):
...     partial_sum += j
...   MyList.append(partial_sum)
...
>>> MyList
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190]

I'm using 1+1 in the outer for loop to prevent a 0 at the beginning of the list. I'm using a sum to put on evidence that I'm thinking of it as start + 1 rather than a start oint different from 1.

This is not the best way to do this, but it is effective and fairly simple to understand, using only simple loops and range(). Using sum() and/or reduce() to produce a nicer solution is possible, but it goes outside the scope of the question.

mencucci
  • 180
  • 1
  • 10
  • 1
    What do you mean with "effective"? – Stefan Pochmann Nov 02 '17 at 17:18
  • I mean it produces the expected result reliably, given a valid input. I'm looking at this generic definition ( https://dictionary.cambridge.org/it/dizionario/inglese/effective ), is it incorrect or incomplete in the context of programming? Would "working solution" be a more appropriate term? – mencucci Nov 02 '17 at 17:20
  • I guess you can say that, but it sounds weird. I don't think I've ever seen it used in programming. Why point out that it's "effective" when everybody expects that anyway? – Stefan Pochmann Nov 02 '17 at 17:28
  • I wanted to emphasize that my solution works correctly for any valid input, in spite of not being the best solution possible. I did not want to give the impression of posting an incorrect solution for simplicity's sake, which could have come from a poor comment. Thank you for your feedback, I will attempt to be clearer and avoid reduntant information in future answers. – mencucci Nov 02 '17 at 17:34
0

You can apply recursive approach to this problem:

l = []

def expand(n):
    if n == 0:
        return 0
    else:
        item = n + expand(n - 1)
        l.append(item)
        return item

expand(21)
print l

[1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231]
ryche
  • 2,004
  • 2
  • 18
  • 27
0

It's called prefix sums or cumulative sum. Easily done with numpy which is de-facto standard for numeric calcualtions.

import numpy as np
data = range(1, 21)
print(np.cumsum(data))
George Sovetov
  • 4,942
  • 5
  • 36
  • 57
AGN Gazer
  • 8,025
  • 2
  • 27
  • 45
0

Standard library for the win!

import itertools
x = range(1, 5)
list(itertools.accumulate(x))

This outputs:

[1, 3, 6, 10]
bnaecker
  • 6,152
  • 1
  • 20
  • 33