You have no control over i when you're using for i in .... It's set to whatever the for loop decides when looping.
Here, just don't use i for your loop index, use an anonymous variable like _ to count 3 times, keep i as a "global" counter:
i=0
while i<10: # just to stop after a while for the demo
print("i initialized as", i)
for _ in range(0,3):
print ("inside for",i)
i = i + 1
print("exit from for i value is",i)
output:
inside for 0
inside for 1
inside for 2
exit from for i value is 3
i initialized as 3
inside for 3
inside for 4
inside for 5
exit from for i value is 6
i initialized as 6
inside for 6
inside for 7
inside for 8
exit from for i value is 9
i initialized as 9
inside for 9
inside for 10
inside for 11
exit from for i value is 12
Aside: while true should be while True. Unlike Java & C++, Booleans are capitalized in python.
You have no control over i when you're using for i in .... It's set to whatever the for loop decides when looping.
Here, just don't use i for your loop index, use an anonymous variable like _ to count 3 times, keep i as a "global" counter:
i=0
while i<10: # just to stop after a while for the demo
print("i initialized as", i)
for _ in range(0,3):
print ("inside for",i)
i = i + 1
print("exit from for i value is",i)
output:
inside for 0
inside for 1
inside for 2
exit from for i value is 3
i initialized as 3
inside for 3
inside for 4
inside for 5
exit from for i value is 6
i initialized as 6
inside for 6
inside for 7
inside for 8
exit from for i value is 9
i initialized as 9
inside for 9
inside for 10
inside for 11
exit from for i value is 12
Aside: while true should be while True. Unlike Java & C++, Booleans are capitalized in python.
The problem here is that you are trying to modify the loop variable of a for loop. Python doesn't stop you from doing i = i + 1 inside the loop, but as soon as control goes back to the top of the loop i gets reset to whatever value is next in the sequence. That's just the way for loops work in Python, it also happens if you loop over a list or tuple rather than a range. Eg,
for i in (2, 3, 5, 7, 11):
print(i)
i = 10 * i
print(i)
output
2
20
3
30
5
50
7
70
11
110
To get the output you want is easy, though. In the following code I replaced your infinite while loop with a small for loop.
i = 0
for j in range(3):
print("\ni initialized as", i)
for i in range(i, i + 3):
print ("inside for", i)
i += 1
output
i initialized as 0
inside for 0
inside for 1
inside for 2
i initialized as 3
inside for 3
inside for 4
inside for 5
i initialized as 6
inside for 6
inside for 7
inside for 8
If the outer loop isn't infinite, you can do this sort of thing with a single loop and an if test. It's more compact, but slightly slower, since it has to perform the test on every loop iteration.
outer_loops = 4
inner_loops = 3
for i in range(outer_loops * inner_loops):
if i % inner_loops == 0:
print("\nIteration", i // inner_loops)
print ("inside for", i)
output
Iteration 0
inside for 0
inside for 1
inside for 2
Iteration 1
inside for 3
inside for 4
inside for 5
Iteration 2
inside for 6
inside for 7
inside for 8
Iteration 3
inside for 9
inside for 10
inside for 11
So I have a particularly nasty API output. It is a list with 20 dictionaries, each dictionary has like 5 others inside of it, and inside some of those there are lists. So I'm breaking down the issue of getting through it.
I'm stuck on how to increment the index of the list so that it goes through all 20 positions of the list. I'm lost. The Java way to do it would be a for loop with i incrementing by i++, and put i into the list index... but I don't think this works?
I have the following code:
i = 0
def next():
global i # <--- declare `i` as a global variable
if (i<rankCount): ## want i to run only as many times as there are dictionaries
# i= i + 1
for roster_member in response["rankings"][i]["run"]["roster"]: # If it's a tank, print the name
if roster_member["role"] == "tank":
print(roster_member["character"]["name"])
i= i + 1How can I achieve this incrementing? I tried to declare a function, set a global variable i, then use an if to check if i is less than rankCount which is 20. If i < 20, a for loop, with an if to check the dictionary value. However, it only printed once. It apparently didn't increment and run the loop again :s
Here is a possible solution (s is your string):
for j in range(len(s) - 1):
print(s[j:j + 2])
Another one:
for c1, c2 in zip(s[:-1], s[1:]):
print(c1 + c2)
By using list comprehension you can do this in a one-liner
s = 'teststring'
r = ' '.join([s[i:i+2] for i in range(len(s)-1)])
print(r)
for index, item in ... already increments index. On your first loop, you are printing (current index 1) then adding (current index 1) + 1 which is 2 then increments + 1 with for loop. So in your second loop, it prints 3.
Create a separate variable outside of the for loop:
numTasksIncomplete = 0
for index, item in enumerate(read_list, 1):
item = item.rstrip('\n')
if item[0] == '':
print(f'{index}. {item}')
numTasksIncomplete += 1
You need to understand the purpose of variable index you are trying to increment.
Currently, index and item and assigned new values every time the loop iterates over read_list. index and task in the for loop with enumerate basically resolves to getting the index and value from read_list one by one.
You are trying to increase the same variable index inside if condition.
Even if you increment it, next time the loop runs, it will overwrite the value.
If you are trying to count the number of tasks that are incomplete, you can use a new variable and name it different that one you are using in the for loop.
Try this :
incomplete_count = 0
for index, item in enumerate(read_list, 1):
item = item.rstrip('\n')
if item[0] == '':
print(f'{index}. {item}')
incomplete_count += 1
There is a fantastic package in Python called itertools.
But before I get into that, it'd serve well to explain how the iteration protocol is implemented in Python. When you want to provide iteration over your container, you specify the __iter__() class method that provides an iterator type. "Understanding Python's 'for' statement" is a nice article covering how the for-in statement actually works in Python and provides a nice overview on how the iterator types work.
Take a look at the following:
>>> sequence = [1, 2, 3, 4, 5]
>>> iterator = sequence.__iter__()
>>> iterator.next()
1
>>> iterator.next()
2
>>> for number in iterator:
print number
3
4
5
Now back to itertools. The package contains functions for various iteration purposes. If you ever need to do special sequencing, this is the first place to look into.
At the bottom you can find the Recipes section that contain recipes for creating an extended toolset using the existing itertools as building blocks.
And there's an interesting function that does exactly what you need:
def consume(iterator, n):
'''Advance the iterator n-steps ahead. If n is none, consume entirely.'''
collections.deque(itertools.islice(iterator, n), maxlen=0)
Here's a quick, readable, example on how it works (Python 2.5):
>>> import itertools, collections
>>> def consume(iterator, n):
collections.deque(itertools.islice(iterator, n))
>>> iterator = range(1, 16).__iter__()
>>> for number in iterator:
if (number == 5):
# Disregard 6, 7, 8, 9 (5 doesn't get printed just as well)
consume(iterator, 4)
else:
print number
1
2
3
4
10
11
12
13
14
15
itertools.islice:
lines = iter(cdata.splitlines())
for line in lines:
if exp.match(line):
#increment the position of the iterator by 5
for _ in itertools.islice(lines, 4):
pass
continue # skip 1+4 lines
print line
For example, if exp, cdata are:
exp = re.compile(r"skip5")
cdata = """
before skip
skip5
1 never see it
2 ditto
3 ..
4 ..
5 after skip
6
"""
Then the output is:
before skip 5 after skip 6
Python implementation of the C example
i = 0
while i < 100:
if i == 50:
i += 10
print i
i += 1
As @[Glenn Maynard] pointed out in the comment if you need to do a very large jumps such as i += 100000000 then you should use explicit while loop instead of just skipping steps in a for loop.
Here's the example that uses explicit while loop instead islice:
lines = cdata.splitlines()
i = 0
while i < len(lines):
if exp.match(lines[i]):
#increment the position of the iterator by 5
i += 5
else:
print lines[i]
i += 1
This example produces the same output as the above islice example.
for the code,
for i in range(0,10):
if i == 3:
i = i + 1
continue
print(i)
the output is going to be,
0
1
2
4
5
6
7
8
9
Breaking down the code,
for i in range(0, 10)
for loop runs for i=0 to i=9, each time initializing i with the value 0 to 9.
if i == 3:
i = i + 1
continue
print(i)
when i = 3, above condition executes, does the operation i=i+1 and then continue, which looks to be confusing you, so what continue does is it will jump the execution to start the next iteration without executing the code after it in the loop, i.e. print(i) would not be executed.
This means that for every iteration of i the loop will print i, but when i = 3 the if condition executes and continue is executed, leading to start the loop for next iteration i.e. i=4, hence the 3 is not printed.
In the provided code when you try to use i in a for loop with range, it always changes to the number provided by range in the function without bothering to look at the increment made to i. so basically if you try list(range(0, 10)) this will give you [0, 2, 3, 4, 5, 6, 7, 8, 9]. so for goes through that list one by one without thinking if any changes were made to i or not.
which if seen
loop_1: i=0
loop_2: i=1
loop_3: i=2
loop_4: i=3 (here now you increment value by 1), i=4
loop_5: i=4 (but the for loop was going though the list from range function so the change didn't do anything)
loop_6: i=5 (and so on until 9)
for i in range(4): print(i) i += 1
How can I make this print:
0
2
For your particular example, this will work:
for i in range(1, 10):
if i in (5, 6):
continue
However, you would probably be better off with a while loop:
i = 1
while i < 10:
if i == 5:
i = 7
# other code
i += 1
A for loop assigns a variable (in this case i) to the next element in the list/iterable at the start of each iteration. This means that no matter what you do inside the loop, i will become the next element. The while loop has no such restriction.
A little more background on why the loop in the question does not work as expected.
A loop
for i in iterable:
# some code with i
is basically a shorthand for
iterator = iter(iterable)
while True:
try:
i = next(iterator)
except StopIteration:
break
# some code with i
So the for loop extracts values from an iterator constructed from the iterable one by one and automatically recognizes when that iterator is exhausted and stops.
As you can see, in each iteration of the while loop i is reassigned, therefore the value of i will be overridden regardless of any other reassignments you issue in the # some code with i part.
For this reason, for loops in Python are not suited for permanent changes to the loop variable and you should resort to a while loop instead, as has already been demonstrated in Volatility's answer.