Home > Blockchain >  How can I increment list items one by one and stop as soon as the sum of the list items has reached
How can I increment list items one by one and stop as soon as the sum of the list items has reached

Time:10-16

I have a list of integers, and I want to add 1 to each integer in the list with every iteration of a while loop. More specifically, I want to perform this operation on the list's integers one by one (left to right) instead of all at once, and stop the loop as soon as the its conditional becomes False, even if that means stopping before the end of the list.

First, I tried the following:

def myfunction(someinput):    
    myintegerlist = [0, 0, 0]
    while sum(myintegerlist) < someinput:
        myintegerlist[0:] = [x 1 for x in myintegerlist[0:]]
    return myintegerlist, sum(myintegerlist)

This doesn't do what I want, because it simultaneously adds 1 to all integers in the list. Thus if someinput = 4, it returns 6 as the sum and [2, 2, 2] as the list, whereas I would like it to stop at [2, 1, 1] before exceeding the input number. So I tried

while sum(myintegerlist) < someinput:
    myintegerlist[indexplace] = [x 1 for x in myintegerlist[indexplace]]
    indexplace  = 1

This was just a guess, and throws "TypeError: 'int' object is not iterable". But I am stuck on how to get through the list items one by one and add 1 to them. Is there a good way to move incrementally through the list with each iteration? Or should I be trying something completely different?

CodePudding user response:

Keep track of the index where you need to add the 1 during the while loop:

def myfunction(someinput):
    myintegerlist = [0, 0, 0]
    increment_index = 0  # next place to add 1
    while sum(myintegerlist) < someinput:
        myintegerlist[increment_index % len(myintegerlist)]  = 1  # add 1 to the element, modulo length of the list to keep the index in range
        increment_index  = 1
    return myintegerlist, sum(myintegerlist)

print(myfunction(4))

Result:

([2, 1, 1], 4)

CodePudding user response:

This is faster

def myfunction(someinput):    
    myintegerlist = [0, 0, 0]
    n=len(myintegerlist)
    _sum=0
    while 1:
        for i in range(n):
            myintegerlist[i] =1
            _sum =1
            if _sum == someinput:

                return myintegerlist, sum(myintegerlist)
print(myfunction(20))

CodePudding user response:

Normally, in order to iterate over the values in a list you would just use

for value in myintegerlist:
    # ...

but this doesn't allow you to directly change the value in the list.

You have to create a loop over the indices of the list.

for i in range(len(myintegerlist)):
    value = myintegerlist[i]

In particular, by assigning to myintegerlist[i] you can change the values in the list.

for i in range(len(myintegerlist)):
    value = myintegerlist[i]
    myintegerlist[i] = new_value

Now you need one additional step, because you don't just want to iterate over each list index once, but possibly many times, until a condition is met. In order to keep the iteration going, you can use the cycle function from the itertools module.

from itertools import cycle

for i in cycle(range(len(myintegerlist))):
    # i = 0, 1, 2, 0, 1, 2, 0, 1, ...

Now you can just add 1 to the value at the current list index and break the loop if the sum of the values has reached the desired amount:

for i in cycle(range(len(myintegerlist))):
    if sum(myintegerlist) >= someinput:
        break
    myintegerlist[i]  = 1

CodePudding user response:

It is bad idea to start every time from 0. Too much meaningless iterations if someinput is a large number.

def get_els(sum_value: int, num_of_els: int = 3) -> tuple:
  _list = [int(sum_value / num_of_els)] * num_of_els
  if sum(_list) == sum_value:
    return _list, sum_value
  while True:
    for idx in range(0, num_of_els):
      _list[idx]  = 1
      if sum(_list) == sum_value:
        return _list, sum_value

print(get_els(2))
print(get_els(4))
print(get_els(5))
print(get_els(10))
print(get_els(20))

Output:

([1, 1, 0], 2)
([2, 1, 1], 4)
([2, 2, 1], 5)
([4, 3, 3], 10)
([7, 7, 6], 20)

More over, if length of list is only 3 elements then loop is not necessary at all:

def get_els(sum_value: int) -> tuple:
  _list = [int(sum_value / 3)] * 3

  if sum_value % 3 == 0:
    return _list, sum_value

  if sum_value % 3 > 1:
    _list[0]  = 1
    _list[1]  = 1
  else:
    _list[0]  = 1
  return _list, sum_value
  • Related