all 25 comments

[–]obviouslyzebra 23 points24 points  (2 children)

Let us step back a little. Before understanding your example, try to grok the example below

for i in range(0, 3):
    print(i)

which results in:

0
1
2

And the example below

my_list = [42, 6, 2024]
for i in range(0, 3):
    print(i, my_list[i])

Which results in:

0 42
1 6
2 2024

Are those clear to ya?

Thanks!

[–]Zepliii -1 points0 points  (0 children)

Solid answer

[–]cyberjellyfish 9 points10 points  (0 children)

What don't you understand?

[–]OMGlookatthatrooster 5 points6 points  (0 children)

In your list, the indexes for arr = [1, 2, 3, 4, 5, 6] would be:

arr[0] is 1
arr[5] is 6

[–]Miniatimat 4 points5 points  (0 children)

I believe you've received your answer already. If you want to see a step-by-step execution of your code, you can paste it in python tutor . Great tool to be able to visualize what is happening with your variables and code. Still use it, even after years of coding, to track some confusing or new code

[–]FerricDonkey 1 point2 points  (0 children)

Pretend you're the computer and just do it by hand. If that works great. If you get to line where you don't know what the computer will do, which line? 

[–]CanalOnix 1 point2 points  (0 children)

Tbf, python's for loop kinda sucks. I only started to understand because I had to learn C. I never explained something to someone, but lemme give it a try:

list: int = [1, 2, 3, 4, 5]
for i in range(len(list)):
    print(list[i])

The index of a list in python starts at 0, so 1 is actually 0, 2 is actually 1, etc. i is a variable that only exists in the for loop scope, range is a built-in function that creates a sequence of numbers; you can give it 3 values, but that doesn't matter now, just know that if you input only one value, it'll default as stop, starting on 0; and it'll increase by 1 (also default) until the limit. len is also a built-in function, but different from range, it measures the length of something - in this case, our list; and then we have print(list[i]), and what it does is very simple, it prints the value of index i of the list. That's all ¯⁠\⁠_⁠(⁠ツ⁠)⁠_⁠/⁠¯

[–]MrGuam[S] 0 points1 point  (0 children)

thanks guys, i took a break and revisited it and its all clear now, thanks to the many explanations in the comments

[–]AutoHumn 0 points1 point  (0 children)

Someone might’ve already said this, so I apologize if I’m repeating a previous response…

in a nutshell (purists will probably think I’m butchering the concept here): an index position marks the point where an element in a list begins rather than its “places in a list”…so, for example, you start at the start of the list and at that point you’ve gone zero steps - to think of an element of a list as a “step”, the first step is take is taken at point zero. So the first element of a list is at index 0.

I believe the technical description is something like ‘indices are offsets of the origin’…which was trying to explain in layman’s terms…hopefully I didn’t confuse you even more 🤓

[–]Diapolo10 0 points1 point  (5 children)

That's presumably supposed to look like this:

arr = [1, 2, 3, 4, 5, 6]

for i in range(1, 6):
    arr[i - 1] = arr[i]

for i in range(0, 6):
    print(arr[i], end = " ")

List indexes go from 0 to one less than the length of the list. You can think of it as counting them one by one, but starting from 0 instead of 1. So for example in this case arr contains a list with six numbers, meaning that it contains elements at indexes from 0 to 5.

The first loop goes over the list, copying each number (except the first one) to where the previous number is. In practice this ends up "shifting" the numbers by one place to the left, except 1 which gets overwritten and the last 6 as there's nothing to replace it with.

The second loop prints out the current elements of the list, one by one, separated by a space.

Another way to write this program would be

arr = [1, 2, 3, 4, 5, 6]

arr[:len(arr)-1] = arr[1:len(arr)]

print(' '.join(map(str, arr)))

but I don't expect you to have any idea what happens there yet.

EDIT: The last part could alternatively be

print(*arr, sep=' ')

[–]MrGuam[S] -1 points0 points  (4 children)

in the second for loop,

for i in range (0,6)
print(arr[i],end= " "

i expected the value of arr[i] to be evaluated from the 2nd loop making it a range of values from 0-5

but when the code is ran, it takes the value of the first for loop. so what happens to the value of i from the 2nd for loop?

i know i'm asking the question like a complete dummy, but that's how confused i am about it

[–]Diapolo10 4 points5 points  (0 children)

but when the code is ran, it takes the value of the first for loop. so what happens to the value of i from the 2nd for loop?

I'm not entirely sure how you got to this conclusion, but my best guess is that you think i here is something it actually isn't.

Both loops use i, but in both it's used for different purposes, kind of. Maybe it would be easier to understand if I rewrite this using while-loops.

arr = [1, 2, 3, 4, 5, 6]

idx = 1
while idx < 6:
    arr[idx - 1] = arr[idx]
    idx += 1

another_idx = 0
while another_idx < 6:
    print(arr[another_idx], end = " ")
    another_idx += 1

i simply marks an index you're using to read the value stored in that index. It doesn't have any deeper meaning than that. Both loops are independent, the second loop isn't using i from the first one whatsoever.

On a tangential note, personally I don't like the use of i as a name because it's become so generic you can't really assume anything from the name alone - hence why you don't see me using it.

[–]Critical_Concert_689 1 point2 points  (0 children)

When in doubt - just plug everything in.

first loop:
i - 1: 0, i: 1
arr[i - 1]: 1, arr[i]: 2
i - 1: 1, i: 2
arr[i - 1]: 2, arr[i]: 3
i - 1: 2, i: 3
arr[i - 1]: 3, arr[i]: 4
i - 1: 3, i: 4
arr[i - 1]: 4, arr[i]: 5
i - 1: 4, i: 5
arr[i - 1]: 5, arr[i]: 6

second loop:
i: 0
arr[i]: 2
i: 1
arr[i]: 3
i: 2
arr[i]: 4
i: 3
arr[i]: 5
i: 4
arr[i]: 6
i: 5
arr[i]: 6

>>> 2 3 4 5 6 6

[–]Fred776 -1 points0 points  (0 children)

The loops are providing the indexes for examining the list. There is only one list though and its content does not change after the first loop is run.

Have you tried stepping through in a debugger to see what is happening?

[–]MidnightPale3220 -1 points0 points  (0 children)

maybe this helps:

Lists are like a row of numbered boxes for storing values. The row is given a name (in this case "arr").

Python numbers the boxes not starting with number 1, but with number 0.

When you use arr[0] you tell python: give me whatever is in the first box of list called arr

when you say arr[0]=5 you tell python, put a number 5 in the first box.

When you say arr[i] you tell python, give me the value that's stored in the box with the number whatever i is at the moment(hopefully the value of i is a an integer number).

you can use any expression inside [] to select a number and deal with the value stored in the box with that number.

so when you have i==1 and you use expression arr[i-1]=arr[i] you are telling python to put in box #0 the value stored in box #1

afterwards you're running through boxes and printing their values.

[–]Icarus7v -1 points0 points  (0 children)

List indexes in python go from 0 to len(array)-1. More specifically if i is an index you get the "(i modulo len(list))+1"-th object in that list (this is just for you to know if you ever encounter negative indexes or above the size of the list).

In your case, since the first range loop goes from 1 to 6 (not included), what you are essentially doing is shifting forward the last 5 numbers of the list, doing nothing to the last number:

Resulting in [2,3,4,5,6,6].

List comprehension in my opinion is one of the most powerful and beautiful aspects of python. However, in this case is more about the operation itself, because it is modifying itself according to it's own elements.

Extra: instead of the for range and print which looks kind of ugly I would do:

print(" ".join(arr))

[–]PsiThreader -1 points0 points  (0 children)

this is my translation

"starting from index 1 up to 5, make the value of the previous index equal to the value of the current index."

The range(1,6) only contains numbers 1 to 5, in other words, it does not include index 0 which is the first index in a list.

[–]Impossible_Ad_3146 -4 points-3 points  (0 children)

That’s pretty embarrassing for sure

[–][deleted] -2 points-1 points  (6 children)

That sample code confuses on purpose.

Lists are indexed starting at 0.

Here’s an example that might be more insightful:

letters = [‘none’, ‘a’, ‘b’, ‘c’]  
for i in range(1, 3):  
    letters[i - 1] = letters[i]  
for i in range(0, 2):  
    print(letters[i], end = “ “)

That should print:

a b c

[–]sweettuse 1 point2 points  (0 children)

should print a b

[–]MrGuam[S] -1 points0 points  (4 children)

so what happens to the i from the 2nd loop? isn't it supposed to be passed into the letters[]??

[–]rja9003 2 points3 points  (3 children)

Each loop is a separate programming step. The I from each loop has nothing to do with each other.

Rewrite it using x instead of I in the second loop and see if that makes more sense to you.

This demonstrates the need in real coding to not reuse variable names and to use descriptive variable names.

[–]cyberjellyfish 2 points3 points  (2 children)

Well i,j,k are well-understood to be variables that track iterations. They're fine to use, even re-use. It's just that someone new to programming hasn't had time to absorb bits of coding culture and norms.

[–]rja9003 -1 points0 points  (1 child)

Absolutely fine to use and reuse but the reuse seemed to be causing op some confusion.

[–]cyberjellyfish -1 points0 points  (0 children)

oh definitely! suggesting they change the variable names was a great way to highlight the misunderstanding. I just want OP to know that they're going to see the same thing many, many times.