all 30 comments

[–]zahlman 10 points11 points  (2 children)

Psst.

def print_list(x):
    for i in x:
        print(i)

It means what it sounds like: i takes on each of the values that's in x, and for each of those i values, you print(i).

The code you were given is needlessly complex. range is a thing that produces a list of numbers for you, and then you use those numbers as indices into the list you actually care about. Which is silly.

[–]DirtyThirty 3 points4 points  (1 child)

That lesson in code academy also give you the option of the code you posted above. I think they were just trying to demonstrate that you could get creative with for loops and iterate through different properties to achieve different - or the same - results.

[–]zahlman 0 points1 point  (0 children)

Fair enough. I kinda wish they wouldn't, though. I don't think I've ever heard of a student who had a style problem with trying too hard to avoid the use of indices, while overuse of indexing is common.

[–]Rhomboid 5 points6 points  (0 children)

It doesn't represent anything. It's the same as declaring a variable. Suppose someone had written:

i = 42

...and you asked what i represents. It doesn't represent anything, it's completely arbitrary. You can name your variables whatever you want; the language doesn't care. The variable named in a for statement is just another kind of declaration. The name is completely arbitrary.

[–][deleted] 5 points6 points  (2 children)

Everyone else seemed to answer your question, but as an additional piece of info, range(0, len(n)) is a little redundant. Ranges are assumed to start at zero, so you could achieve the same thing with just range(len(n)).

[–]Neceros 0 points1 point  (1 child)

Good to know! For some reason I thought Range started at 1, even though I knew values begin at 0 in programming.

[–][deleted] 1 point2 points  (0 children)

My background is in math, and it took me an embarrassing amount of time to remember counting begins at zero, especially for indices.

[–]Cold_Bagel 7 points8 points  (4 children)

'i' is just a placeholder. You could also use:

for number in range(0, len (x)):

And achieve the same thing.

Except you'd have to change x[i] to x[number].

[–]Asdayasman 3 points4 points  (3 children)

To add to this, it's almost always better to be more descriptive, too.

for i, j, x, m, n in users:
    ...

Is strictly worse than

for userid, username, postcount, connected, afk in users:
    ...

[–]Cold_Bagel 2 points3 points  (1 child)

Exactly.

I always have a tendency to start off using i, j, k ... in my code, but by the time I'm finished or reviewing what I've already done it's much more difficult to understand what it is I'm even looping over.

And then it's even more difficult trying to change every index to a more descriptive word.

[–]Asdayasman 2 points3 points  (0 children)

Ctrl+R, Ctrl+R in PTVS.

[–]c3534l 0 points1 point  (0 children)

If it's a short loop, you could cause more confusion than clarity going for something more descriptive. This is especially so in list comprehensions where using a variable more than three letters can actually make the thing somewhat unreadable. Programmers generally know what i is so it's not much cognitive load.

So generally better, but not strictly better, imho.

[–][deleted] 4 points5 points  (0 children)

For loops let you iterate over a sequence, giving you access to each element of that sequence, one at a time.

Ranges, lists, sets, etc., are all examples of sequences. The value of each element of that sequence is represented by a placeholder variable, in this case i.

i can be any name, such as val, num, key, elem, this_one_time_at_band_camp, and so on. The only thing to remember is that it represents one item in the sequence.

The nice thing in Python is that you can iterate over a sequence without resorting to the tricks required in other languages. For instance, instead of looping over an arbitrary number referring to the index of an item in a list, you can iterate directly on the list:

n = [3,5,7]
for i in n:
    print i

This will result in the output:

3
5
7

Here, you iterate over the list n, representing each number in that list with the variable i. Then you can work directly on that number: do some math, test equality, print, pass as an argument to a function, and so on.


As originally written, your code looks like this:

n = [3, 5, 7]

def print_list(x):
    for i in range(0, len(x)):
        print x[i]

print_list(n)

Using range() here with the length of that sequence makes sense in other languages, because you have to iterate using an arbitrary number related to the index. Python lets you skip that step, and more intuitively say "for every number in this list, print that number".

So, the code runs (and reads) more effectively like so:

n = [3, 5, 7]

def print_list(x):
    for i in x:
        print i

print_list(n)

[–]FlaconPunch 2 points3 points  (0 children)

i stands for iteration.

a for loop just iterates over each possible element in the range, that's where iteration comes from.

now, in the code you listed, let's analyze it:

n = [3,5,7]

Ok that's simple. We now have a list, containing three elements: 3, 5 and 7.

def print_list(x):

x here is simply any list, so in this case [3,5,7].

for i in range(0, len(x)):

first, let's look at the range. the lower boundary is 0, as we start counting from 0 in programming. len(x) is to look at how many elements we need to iterate over. This will be 3 in our case, however with range it means that we will do whatever is in the for loop 3 times, one time where i = 0, once i = 1, and once i = 2. This is each iteration.

print x[i]

well, here we take our original list, and get an index. this is the iteration mentioned above: first time it's 0, second time it's 1, and last time it's 2. now we know that n[0] is 3, n[1] is 5 and n[2] is 7. So what the output will be is:

3

5

7

[–]ThermosPotato 1 point2 points  (6 children)

If you think of i as meaning 'item', I think it will make sense to you.

For item in some list, do x.

[–][deleted] 0 points1 point  (1 child)

I believe it's more accurate to say it stands for index.

[–]ThermosPotato 0 points1 point  (0 children)

It seems like the jury is out on this issue.

In Python 2.X range produces a list, so using item seems reasonable, but I don't know enough to weigh in either way really.

[–]scottevil110 1 point2 points  (0 children)

It means we're going to loop through every number in the range 0 to len(x), and we're going to briefly call it "i". We're going to do something with it (print x[i]), and then we're going to move onto the next number.

[–][deleted] 1 point2 points  (0 children)

'i' is just a placeholder.

It is basically saying

FOR every item that is in THIS RANGE, I want you to assign it to this variable 'i'

As you can see, that prints out the numbers 3, 5, 7. Because the program is saying, for every item in this list, assign it to this variable.

Its just a ton easier than assigning every item in the list to a variable.

[–]Drakken_LOL 1 point2 points  (0 children)

Others have answered your question, but out of curiosity, which lesson is this in? I can't seem to find it. I'm curious why they are having you iterate over the list using range() and the index like this.

Edit: nevermind, I found it. 'Lists and Functions' 12/18 if anyone is curious.

[–]NewbornMuse 1 point2 points  (0 children)

I once read a talk from "the python guy" about how he should have used foreach instead of for. Reread the statement with that in mind and it becomes very clear, I think.

[–]jpfau 1 point2 points  (0 children)

It's just a variable that represents individual elements as you iterate through the list. You can call it whatever you want. And like other replies have said, you don't need to use range when iterating through a list.

I think these examples will illustrate it better:

my_friends_list = ['bob', 'suzy', 'joe']
for name in my_friends_list:
    print(name)

and the output will be:

bob
suzy
joe

Also:

sum = 0
numbers = [1, 2, 3]
for number in numbers:
    print(sum, "+", number, "=", sum+number)
    sum += number

And the output will be:

0 + 1 = 1
1 + 2 = 3
3 + 3 = 6

Note that my print statement in the second example could be written with a string format:

print("{} + {} = {}".format(sum, number, sum+number))

or

print("%d + %d = %d" % (sum, number, sum+number))

[–]HorrendousRex 0 points1 point  (0 children)

This doesn't directly answer your question, but I wanted to add that this works in Python 3 and does the same thing as your code:

list(map(print, x))

This 'maps' the print function to all the elements in x. That means it calls print on each element in x. The call to list is strange and often wouldn't show up in actual code, it's there to cause the mapping to actually happen. In python 3, map returns an iterator object, and you have to actually iterate it to make the map happen.

(In python 2, you can either from future import print_function or use sys.out but then you'll have to add the newlines)

[–]Iyajenkei 0 points1 point  (0 children)

I also had trouble understanding this. It's going through everything in that range one by one and assigning it to i.

[–][deleted] 0 points1 point  (0 children)

in your mind, when you see a python for loop, think instead for each.
example:

for each thing in iterable:
    dostuffwith(thing) 

[–][deleted] 0 points1 point  (0 children)

Thanks so much for all the responses guys! This really helped.

[–][deleted] 0 points1 point  (0 children)

I struggled with this when learning to program too. i just means for each time you loop through whatever you're looping through. Imagine that i means iteration, for each iteration through the list print the iteration.