Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there are more pythonic way to write a while loop that only updates a variable?

Tags:

python

numpy

I have this while loop, and I was wondering if their is a more pythonic way to write it:

k = 1
while np.sum(s[0:k]) / s_sum < retained_variance:
    k += 1

s is a numpy vector. Thanks!

like image 610
Max Avatar asked Mar 16 '14 19:03

Max


People also ask

Can you update a variable inside a while loop?

The best way to make the condition change from True to False is to use a variable as part of the Boolean expression. We can then change the variable inside the while loop.

How do you update a value in a while loop in Python?

You need to initialize previous guess before while loop Otherwise it will be initialized again and again. You have to set the value of previous guess to x the computer generator and when you move on after loop you have to update the previous guess to next simply like this: Add before while { previous_guess = x }

Is while true Pythonic?

The "while true" loop in python runs without any conditions until the break statement executes inside the loop. To run a statement if a python while loop fails, the programmer can implement a python "while" with else loop. Python does not support the "do while" loop.

What happens if the test variable for a while loop is not updated?

You are only printing the output of test() , not updating the variable a so this will always be 0 at each iteration of your loop. when you call test(a) you just print the result, a is never updated - i.e. it stays 0, you just throw away the value returned.


4 Answers

I'd say it's pretty pythonic: explicit is better than implicit.

like image 102
jminuscula Avatar answered Oct 01 '22 12:10

jminuscula


Probably not the most efficient solution, but fast if most of the array needs to be searched:

import numpy as np

ss = np.cumsum(s)  # array with cumulative sum
k = ss.searchsorted(retained_variance*s_sum) # exploit that ss is monotonically increasing

EDIT: Simon pointed out that

k = np.cumsum(s).searchsorted(retained_variance*s_sum) + 1

is the value which corresponds to the question.

like image 30
Dietrich Avatar answered Oct 01 '22 12:10

Dietrich


The last line of the following code will find the value of k in one line:

import numpy as np
import math

s = np.array([1,2,3,4,5,6,7,8,9])
s_sum = 1
retained_variance = 4.3

k = 1
while np.sum(s[0:k]) / s_sum < retained_variance:
    k += 1

print (k)

print (np.ceil(np.interp(retained_variance,s.cumsum()/s_sum,range(1,len(s)+1))))
like image 27
Simon Avatar answered Oct 01 '22 13:10

Simon


this is more like Haskell than python:

>>> from itertools import count, dropwhile
>>> pred = lambda k: np.sum(s[:k]) / s_sum < retained_variance
>>> head = next  # just to look more like haskell
>>> head(dropwhile(pred, count()))

edit: this will be more efficient:

>>> from itertools import dropwhile, accumulate
>>> pred = lambda x: x[1] / s_sum < retained_variance
>>> head = next
>>> head(dropwhile(pred, enumerate(accumulate(s), start=1)))[0]
like image 29
behzad.nouri Avatar answered Oct 01 '22 12:10

behzad.nouri