I am having trouble understanding a Python for loop. For example, here is some code I've made while I'm learning:
board = []
for i in range (0,5):
board.append(["O"] * 5)
Don't worry about what the code does, I just don't understand what the "i" variable means.
Think of it as substitution.
range(0,5) is [0,1,2,3,4]. The for-loop goes through each element in the list, naming the element i.
for i in range(0,5):
# Starts with 0
print i # prints 0
# now goes back, goes through next element in list: 1.
Prints 0,1,2,3,4.
In your example, i is a placeholder. It is used simply just to loop something x amount of times (in this case, five as the length of range(0,5) is 5)
Also, have fun learning python at Codecademy (I recognise the task :p)
It's an iterator, you can see it as a bucket that stores the result of each iteration; the thing that adds confusion is the fact that it's simply unused in your script, this is another script with a "more involved" use of iterators.
fruits = ['banana', 'apple', 'strawberry', 'coconut', 'cherry']
for yup in fruits:
print(yup)
as you can see you can name it as you want, it's the syntax that makes that word an iterator.
It's an unused variable. Python syntax requires a variable in that position, but you don't do anything with it since you simply want to repeat an action 5 times.
Some people prefer the convention of naming an unused variable like this _:
for _ in range(5)
but this name can interfere with gettext.
In short, i refers to the current element in the list.
Your list is defined as: 0, 1, 2, 3, 4 and 5. Therefore i will iterate this list and assign itself to the next item, i is 0, next iteration i will be 1, next iteration i will be 2 etc.
Directly from python.org:
The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence. For example (no pun intended)
words = ['cat', 'window', 'defenestrate']
for w in words:
print w, len(w)
Results in:
cat 3
window 6
defenestrate 12
http://docs.python.org/2/tutorial/controlflow.html
The for loop iterates over the given list of objects which is [0, 1, 2, 3, 4] obtained from range(0,5) and in every iteration, you need a variable to get the iterated value. That is the use i here. You can replace it with any variable to get the value.
for n in range(0, 5):
print n #prints 0, then 1, then 2, then 3,then 4 in each iteration
Another example:
for n in ('a', 'b', 'c'):
print n #prints a, then b, then c in each iteration
But in the code you have given, the variable i is not used. It is being used. just to iterate over the list of objects.
In c/java the for loop wiil be:
for(int i=0;i<=10;i++)
{
//for-loop-body
}
here for every iteration i will be incrementing +1 value till i reaches 10, after that it comes out of loop.
In same way,in python the for loop looks like:
for i in range(0,10):
//for-loop-body
here i performs same operation and i is just a variable to increment a value.
Related
C:
# include <stdio.h>
main()
{
int i;
for (i=0; i<10; i++)
{
if (i>5)
{
i=i-1;
printf("%d",i);
}
}
}
Python:
for i in range(10):
if i>5: i=i-1
print(i)
When we compile C code, it goes into a infinite loop printing 5 forever, whereas in Python it doesn't, why not?
The Python output is:
0 1 2 3 4 5 5 6 7 8
In Python, the loop does not increment i, instead it assigns it values from the iterable object (in this case, list). Therefore, changing i inside the for loop does not "confuse" the loop, since in the next iteration i will simply be assigned the next value.
In the code you provided, when i is 6, it is then decremented in the loop so that it is changed to 5 and then printed. In the next iteration, Python simply sets it to the next value in the list [0,1,2,3,4,5,6,7,8,9], which is 7, and so on. The loop terminates when there are no more values to take.
Of course, the effect you get in the C loop you provided could still be achieved in Python. Since every for loop is a glorified while loop, in the sense that it could be converted like this:
for (init; condition; term) ...
Is equivalent to:
init
while(condition) {
...
term
}
Then your for infinite loop could be written in Python as:
i = 0
while i < 10:
if i > 5:
i -= 1
print i
i += 1
The two constructs are both called for loops but they really aren't the same thing.
Python's version is really a foreach loop. It runs once for each element in a collection.
range(10) produces a list like [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] So the for loop runs once for each member of the collection. It doesn't use the value of i in deciding what the next element is, it always takes the next element in the list.
The c for loop gets translated into the equivalent of
int i = 0
while i < 10:
...
i++;
Which is why you can manipulate the i.
Because your two examples are completely different things.
range(10) in python produces a list of values 0 - 9, then for i in returns each value as i. This is generally referred to as a "for-each" loop. You are operating on a value, not the iterator, when you say i=i-1 in your python example.
http://docs.python.org/tutorial/controlflow.html
The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence. For example (no pun intended):
a = ['cat', 'window', 'defenestrate']
for x in a:
print x, len(x)
It is not safe to modify the sequence being iterated over in the loop (this can only happen for mutable sequence types, such as lists). If you need to modify the list you are iterating over (for example, to duplicate selected items) you must iterate over a copy.
Of course the sequence generated by range is not mutable.
I am just trying to merge two sorted lists into one sorted list. I know it is a simple task and plenty solutions online, but my question is different. Here's my code:
def merge(list1, list2):
len1 = len(list1)
len2 = len(list2)
list3 = []
pointer = 0
for i in range(len1):
if (list1[i] >= list2[pointer]):
while (pointer < len2 and list1[i] >= list2[pointer]):
list3.append(list2[pointer])
pointer += 1
i -= 1
else:
list3.append(list1[i])
while (pointer < len2):
list3.append(list2[pointer])
pointer += 1
return list3
if __name__ == "__main__":
print(merge([1, 2, 3, 10, 11, 22], [4, 5, 6, 7, 20, 21, 30]))
I did debugging and I was confused to see that when I decrease the value i by 1, for example from 3 to 2, on the next iteration it goes back to 4. I have no idea why? You can check it by running the code and seeing the result. I just need explanation why that is happening. Thanks
I was confused to see that when I decrease the value i by 1, for example from 3 to 2, on the next iteration it goes back to 4. I have no idea why?
Because for i in range(x) means "execute the for body with i assuming the values of 0 through x-1". Assigning a different value to i does not affect its value in the next iteration.
In other words, for i in range(10) is not a translation of C's or JavaScript's for (i = 0; i < 10; i++). Instead, you can think of it as for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. Seen like that, it is clear that changing one value of i will not affect the subsequent value, which is blindly taken out of a pre-generated list. If you need to modify the iteration progress based on changing conditions, you can write the C/JS-style loop explicitly:
i = 0
while i < len1:
# ... loop body goes here ...
i += 1
Written like this, modifying i in loop body will affect iteration in the way you expected.
You are editing i inside the for loop that runs on i. I don't believe it will work the way you intend it.
Also, you can simply merge the lists and sort the outcome with this:
list1 = [1,2,3,10,11,22]
list2 = [4,5,6,7,20,21,30]
list3 = list1 + list2
list3.sort()
print(list3)
Hope this helps.
This is because range() is a generator function. It does not create the list of numbers, as you might expect, but generates a new number as you need it. And, even if it created the list, the numbers would be taken from the list, one after the other, regardless how you modify them. You can think of the result of range() in a sense as 'read-only'. user4815162342 below is right, you should not confuse it with a C-style loop. More like a Fortran loop, where the number of iterations is computed in advance.
From https://pynative.com/python-range-function/:
Python 3’s range uses the generator. Python 3’s range() will produce value when for loop iteration asked for it. i.e., it The range() doesn’t produce all numbers at once.
Python range() function returns an immutable sequence object of integers, so it is possible to convert range() output to the Python list. Use list class to convert range output to list. Let’s understand this with the following example.
I am learning the python from the Codeacademy website and I came across the loops section which is a little vague and hard to me. When the website wants to explain how does a for loop works, it gets help from lists. Like so:
for i in list34:
#Some codes
The website says that when you run a for loop statement for a list, the for loop would iterate through the elements of the list then save them in i variable.
I just don't get the iterating through concept!
What does it mean?
Maybe some code example will help!
>>> li = [4,3,1,2,0]
>>> for x in li:
... print(x)
...
4
3
1
2
0
>>>
What the for loop does is, it takes one item in the list at a time and assigns that item to the variable x. As the for loop takes items of lists one by one, it is called iterating through/on the list.
for i in list34:
#Some codes
This snippet will go through all the items of list34 (i.e., iterate through them).
In each iteration ("step" of the loop), i will be assigned the next value from the list, so your code could do something with it (e.g., print it out).
iterating over a list, or any data structure for that matter, means that it just takes every element, one after the other, from the given structure an does something with it.
in this case you have your i elements and you do stuff with them inside the for loop. the for statement makes sure, that every element of the list is handled.
The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence. For example (no pun intended):
# Measure some strings:
words = ['cat', 'window', 'defenestrate']
for w in words:
print w, len(w)
If you need to modify the sequence you are iterating over while inside the loop (for example to duplicate selected items), it is recommended that you first make a copy. Iterating over a sequence does not implicitly make a copy. The slice notation makes this especially convenient:
for w in words[:]: # Loop over a slice copy of the entire list.
if len(w) > 6:
words.insert(0, w)
words
If you do need to iterate over a sequence of numbers, the built-in function range() comes in handy. It generates lists containing arithmetic progressions:
range(10)
The given end point is never part of the generated list; range(10) generates a list of 10 values, the legal indices for items of a sequence of length 10. It is possible to let the range start at another number, or to specify a different increment (even negative; sometimes this is called the ‘step’):
range(5, 10)
range(0, 10, 3)
range(-10, -100, -30)
To iterate over the indices of a sequence, you can combine range() and len() as follows:
a = ['Mary', 'had', 'a', 'little', 'lamb']
for i in range(len(a)):
print i, a[i]
Read More: docs.python.org
How to use more than one condition in Python for loop?
for example in java:
int[] n={1,2,3,4,6,7};
for(int i=0;i<n.length && i<5 ;i++){
//do sth
}
How dose the python for loop do this?
The Python for loop does not, itself, have any support for this. You can get the same effect using a break statement:
n = [1, 2, 3, 4, 6, 7]
for i in n:
if i >= 5:
break
# do something with i
In Python, a for is really a foreach that iterates over some "iterator" or some "iterable object". This is even true when you just want to repeat a specific number of times:
for i in range(1, 8):
# do something with i
In Python 2.x, the above for loop builds a list with the numbers 1 through 7 inclusive, then iterates over the list; in Python 3.x, the above loop gets an "iterator object" that yields up the values 1 through 7 inclusive, one at a time. (The difference is in the range() function and what it returns. In Python 2.x you can use xrange() to get an iterator object instead of allocating a list.)
If you already have a list to iterate over, it is good Python to iterate over it directly rather than using a variable i to index the list. If you still need an index variable you can get it with enumerate() like so:
n = [3, 5, 10, "cat", "dog", 3.0, 4.0] # list can contain different types
for i, value in enumerate(n):
# we only want to process the first 5 values in this list
if i >= 5:
break
# do something with value
EDIT: An alternate way to solve the above problem would be to use list slicing.
for value in n[:5]:
# do something with value
This works if n is a list. The for loop will set value to successive items from the list, stopping when the list runs out or 5 items have been handled, whichever comes first. It's not an error to request a slice of longer length than the actual list.
If you want to use the above technique but still allow your code to work with iterators, you can use itertools.islice():
from itertools import islice
for value in islice(n, 5):
# do something with value
This will work with a list, an iterator, a generator, any sort of iterable.
And, as with list slicing, the for loop will get up to 5 values and it's not an error to request an islice() longer than the number of values the iterable actually has.
The direct equivalent of your Java code is a while loop:
n = [1, 2, 3, 4, 6, 7]
i = 0
while i < len(n) and i < 5:
# do sth
i += 1
You could also do:
n = [1, 2, 3, 4, 6, 7]
for x in n[:5]:
# do sth
Here is one way to have two or more conditions with the for loop, which is what the question actually asks. The point I am trying to make is that it can be done, but isn't very pythonic and it's generally not a good idea to try to rewrite code from another language line by line.
from itertools import takewhile, count
n=[1,2,3,4,6,7]
for i in takewhile(lambda i:i<len(n) and i<5, count()):
print(i)
You can write a while loop with the same sort of logic (but in Python, && is spelled and, and || is spelled or); or you can use a for loop that iterates over a sequence and then add extra logic to break out of the loop.
In Python, we prefer not to use integers to index into a container. This would actually break a lot of our code, because we do not check the data types at compile-time, and some containers cannot be indexed into. Wanting to index into a container is already a design smell: the fact that everything is in a sequential container is supposed to mean that none of the elements are "special", or we would have kept them separate. Iteration is iteration, and we should not go out of our way to make it more complicated.
Assuming that you want the ith item of n somewhere in the loop, enumerate saves us from typing n[i] all over the place - the value will be stored in the variable item
n = [1,2,3,4,6,7]
for i, item in enumerate(n):
if i>=5:
break
# do something
print item # for example
Note that the loop will terminate automatically if the length of n is less than 5
Python's for is not like the for in languages based on C syntax. In Python, for iterates over a sequence, whereas in C it loops while a condition is true. This is a profound difference.
The C-like for can be replaced roughly with the following code:
i = 0;
while (i < n.length && i < 5) {
// do sth
i++;
}
(There are some complications from break and continue, but let's ignore those for now.)
This rewrite also indicates a way to do what you want in Python: use while:
i = 0
while i < len(n) and i < 5:
// do something
i += 1
In your particular case, however, it is easiest to use for with a suitable list of indexes:
for i in range(min(len(n), 5)):
// do something
range will return a list of integers (0, 1, 2, ...) and what you want is to have the list go up to 5, or the length of your array, whichever is smaller. The above code achieves that.
The for statement in Python iterates a "list" of objects (I put list in quotes because I mean it in the generic sense, it can iterate over anything that is iterable).
To code a conditional loop (rather than iterating until completion), use while:
n = [1, 2, 3, 4, 6, 7]
i = 0
while i < len(n) and i < 5:
# do stuff
i += 1
Now just to be complete, your example could also be written as:
n = [1, 2, 3, 4, 6, 7]
for i in range(0,min(len(n),5)):
# do stuff
or:
n = [1, 2, 3, 4, 6, 7]
for i in range(0,len(n)):
if i >= 5:
break
# do stuff
print max(3 for i in range(4))
#output is 3
Using Python 2.6
The 3 is throwing me off, heres my attempt at explaining whats going on.
for i in range(4) makes a loop that loops 4 times, incrementing i from 0 to 3 at the start of each loop. [no idea what the 3 means in this context...] max() returns the biggest iterable passed to it and the result is printed to screen.
3 for i in range(4) is a generator that yields 3 four times in a row and max takes an iterable and returns the element with the highest value, which is, obviously, three here.
This evaluates to:
print max([3,3,3,3])
... which is an elaborate way to say print 3.
expr for x in xs is a generator expression. Typically, you would use x in expr. For example:
[2*i for i in range(4)] #=> [0, 2, 4, 6]
It can be rewritten as:
nums = []
for i in range(4):
nums.append(3)
print max(nums) # 3! Hurrah!
I hope that makes its pointlessness more obvious.
The expression:
print max(3 for i in range(4))
is printing the result of the max() function, applied to what is inside the parentheses. Inside the parentheses however, you have a generator expression creating something similar to an array, with all elements equal to 3, but in a more efficient way than the expression:
print max([3 for i in range(4)])
which will create an array of 3s and destroy it after it is no longer needed.
Basically: because inside the parentheses you will create only values that are equal, and the max() function returns the biggest one, you do not need to create more than one element. Because with the number of elements always equal to one, the max() function becomes not needed and your code can be effectively replaced (at least in the case you have given) by the following code:
print 3
That is simply all ;)
To read more about differences between comprehension and generator expression, you can visit this documentation page.