How do I increment a counter inside a while test of Python
Solution 1
The problem you can't do that way in Python is a restriction of Python syntax. Let's get what does while
look like from documentation:
while_stmt ::= "while" expression ":" suite
["else" ":" suite]
As You can see you must put expression before ":", while x += 1
is a statement (and statements doesn't return any value so cannot be used as a condition).
Here's what does this code look like in Python:
i += 1
while a[i] < v:
if i == hi:
break
i += 1
Though it works, it's most likely not a Python way to solve your problem. When you have a collection and you want to use indices you have to look forward to redesigning your code using for
loop and enumerate
built-in function.
P.S.
Anyway, direct code porting between languages with absolutely different philosophies is not a good way to go.
Solution 2
The Java code sets i to the index of either the first element >= a[lo], or to hi, whichever appears first. So:
v = a[lo]
for i in range(lo+1, hi+1):
if a[i] >= v:
break
Solution 3
If you want to iterate over all the objects in a list or any "iterable" thing, use "for item in list". If you need a counter as well, use enumerate. If you want a range of numbers use range or xrange.
But sometimes you really do want a loop with a counter that just goes up which you're going to break out of with break or return, just like in the original poster's example.
For these occasions I define a simple generator just to make sure I can't forget to increment the counter.
def forever(start=0):
count = start
while True:
yield count
count += 1
Then you can just write things like:
for count in forever():
if do_something() == some_value:
break
return count
boardrider
Updated on June 10, 2020Comments
-
boardrider almost 4 years
How would you translate the following Java idiom to Python?
Comparable[] a, int lo, int hi; int i = lo, j = hi+1; Comparable v = a[lo]; while (a[++i] < v) if (i == hi) break;
My problem is that in the while test I cannot have a
++i
ori += 1
. -
michelson over 11 yearsBTW - I wouldn't call this a syntax limitation. It is a philosophical restriction that the language imposes.
-
boardrider over 11 yearsMy code needs to check that "a[++i] < v" namely, i needs to be incremented prior to the test. The solution you present, does not do that (it checks a[i]).
-
Rostyslav Dzinko over 11 years@D.Shawley, will agree with you here. The word "limitation" was born in my mind due to long-term communication with Ruby-guys and in Ruby everything is an expression).
-
Martijn Pieters over 11 years@user1656850: the code in the answer as it stands now increments
i
, then does the test. It's functionally the same. -
boardrider over 11 yearsThanks for the answers. However, two problems: A for loop is good if the number of iteration is known in advance, so it may apply in my example, but not in all cases (whereas a while loop can be applied in all cases). The solution you give will not increment the i on the last test (as the loop body will not be entered into), whereas the Java code will increment the i on the last check (because the ++i is done prior to the check).
-
yantrab over 11 years@user1656850: your analysis of the example is wrong. The Python while loop here will produce the same results as your Java code.
-
boardrider over 11 yearsNed, in the Java case, when a[X] >= V, the i will be one greater than in the Python case.
-
yantrab over 11 years@user1656850: In the java case, the i is pre-incremented, so if the test fails, it will be because a[i] >= v. The same is true of the Python code. When the loop ends due to finding an element >= v, the value of i after the loop will be the index of the offending element.