Help understand the code (prison break)

Hi, im finding this very difficult, i was at a loss on what to write here.

The way i see this is:

  1. Assigning a new variable called index with the value of 0
  2. Creating a for loop with the variable row that iterates over all the rows
  3. Now this is where my brain melts, data is already a variable so its getting all the data, then it looks like the variable index is being put in a list which is equal to everything before the last row.
  4. Index += 1. so the index plus the index is equal to 1. im very confused by this, because if the loop goes round again, wont this equal to 2?

i honestly am doubting if i can do this. its a simple for loop but my brain just cant understand the link between this. it just seems like a riddle.

thanks for any help.

index = 0
for row in data:
    data[index] = row[:-1]
    index += 1
1 Like

Sorry to hear your frustrations and doubt. I don’ t have anything magical to say that can stop you from feeling that way, except to say that if you’re willing to work through it, I and others here will do our best to help you solve any problems you face.

A for loop can be tricky even if it’s simple. This is very normal and something that many people experience especially when they’re not used to thinking in terms of loops or iterations.

I think you got it almost right especially from point 1-3.

For point 3, you’re essentially updating a row in data with the same row except for the last element. I know it can be confusing because the variable name for the iterator is also row.

Let’s consider a hypothetical data:

data = [ 
                 ['a', 'b', 'c'],

                 ['d', 'e', 'f'],

                 ['g', 'h', 'i']
]

Recall that you can select one row by using a number surrounded by square brackets e.g. [0]:

data = [ 
                 # data[0]
                 ['a', 'b', 'c'],
                # data[1]
                 ['d', 'e', 'f'],
                # data[2]
                 ['g', 'h', 'i']
]

# for example
first_row = data[0]

How does this relate to the for loop?

Consider this:

data = [ 
                 ['a', 'b', 'c'],
                 ['d', 'e', 'f'],
                 ['g', 'h', 'i']
]

index = 0
for row in data:
    data[index] = row[:-1]
    index += 1

When you use for row in data, you’re essentially telling Python to iteratively assign row to a row in data.

In the first iteration: row = data[0]

In the second iteration: row = data[1]

In the third iteration: row = data[2]

And so forth until it reaches the end of data.

Here’s what’s happening in the loop:

First Iteration

Step 1

index = 0
for row in data:
    # step 1: row = data[0]
    # row right now has the value [ 'a', 'b', 'c' ] 
    #

    data[index] = row[:-1]
    index += 1

Step two

index = 0
for row in data:
    # Step 1: row = data[0]
    # row right now has the value [ 'a', 'b', 'c' ] 

    # Step 2: get an element/row from data according to the index variable
    # What is the value of index right now? It is 0
    # So, that means data[index] is data[0]
    data[index] = row[:-1]
    index += 1

Step three

index = 0
for row in data:
    # Step 1: row = data[0]
    # row right now has the value [ 'a', 'b', 'c' ] 

    # Step 2: get an element/row from data according to the index variable
    # What is the value of index right now? It is 0
    # So, that means data[index] is data[0]

    # Step 3: assign everything from row except the last element in it to data[index]
    # Look back at Step 1, row actually has the same value as data[0]
    # That means a complete row is ['a', 'b', 'c']

    # But we don't want everything inside that row. We want to exclude the last one
    # So we use list slicing row[:-1] to grab everything except the last element
    #  Now the value to assign is only ['a', 'b']
    data[index] = row[:-1]
    index += 1

Step four

index = 0
for row in data:
    # Step 1: row = data[0]
    # row right now has the value [ 'a', 'b', 'c' ] 

    # Step 2: get an element/row from data according to the index variable
    # What is the value of index right now? It is 0
    # So, that means data[index] is data[0]

    # Step 3: assign everything from row except the last element in it to data[index]
    # Look back at Step 1, row actually has the same value as data[0]
    # That means a complete row is ['a', 'b', 'c']

    # But we don't want everything inside that row. We want to exclude the last one
    # So we use list slicing row[:-1] to grab everything except the last element
    # Now the value to assign is only ['a', 'b']

    # Step 4: what happens after the assignment in Step 3?
    # That means that the first row in data which is data[0]  is now ['a', 'b'] instead of the previous ['a', 'b', 'c']
    # Or, you can look at it like this: data[0] = ['a', 'b']
    data[index] = row[:-1]
    index += 1

Step five

index = 0
for row in data:
    # Step 1: row = data[0]
    # row right now has the value [ 'a', 'b', 'c' ] 

    # Step 2: get an element/row from data according to the index variable
    # What is the value of index right now? It is 0
    # So, that means data[index] is data[0]

    # Step 3: assign everything from row except the last element in it to data[index]
    # Look back at Step 1, row actually has the same value as data[0]
    # That means a complete row is ['a', 'b', 'c']

    # But we don't want everything inside that row. We want to exclude the last one
    # So we use list slicing row[:-1] to grab everything except the last element
    # Now the value to assign is only ['a', 'b']

    # Step 4: what happens after the assignment in Step 3?
    # That means that the first row in data - data[0] -  is now ['a', 'b'] instead of the previous ['a', 'b', 'c']
   # Or, you can look at it like this: data[0] = ['a', 'b']
    data[index] = row[:-1]

    # Step 5: Incrementing the index
    # index is currently 0

    # We use index += 1 to increment index by 1
    # Remember that += is actually a shortcut of sorts
    # index += 1 is actually the same as index = index + 1

    # Thus, the full expression is index = 0 + 1
    # After that, index is now 1 
    # We'll use the new index in the second iteration not the current iteration
    index += 1

Alright, the first iteration is now complete.

Next iteration…

Second Iteration

Step 1-5

index = 0
for row in data:
    # Step 1: row = data[1]
    # row right now has the value [ 'd', 'e', 'f' ] 

    # Step 2: get an element/row from data according to the index variable
    # What is the value of index right now? It is 1. Remember that we've incremented it by 1 in the first iteration.
    # So, that means data[index] is data[1]

    # Step 3: assign everything from row except the last element in it to data[index]
    # Look back at Step 1, row actually has the same value as data[1]
    # That means a complete row is ['d', 'e', 'f']

    # But we don't want everything inside that row. We want to exclude the last one.
    # So we use list slicing row[:-1] to grab everything except the last element
    # Now the value to assign is only ['d', 'e']

    # Step 4: what happens after the assignment in Step 3?
    # That means that the first row in data which is  data[1] is now ['d, 'e'] instead of the previous ['d', 'e', 'f']
    # Or, you can look at it like this data[1] = ['d', 'e']
    data[index] = row[:-1]

    # Step 5: Incrementing the index
    # index is currently 1

    # We use index += 1 to increment index by 1
    # Remember that += is actually a shortcut of sorts
    # index += 1 is actually the same as index = index + 1

    # Thus, the full expression is index = 1 + 1
    # After that, index is now 2
    # We'll use the new index in the third iteration not the current iteration
    index += 1

The third iteration will follow the same pattern.

Feel free to ask questions if you need more clarifications.

4 Likes

Hi, thank you very much for this detailed breakdown. That makes a lot of sense and I appreciate the effort to help me.

So when the index is at 0, it gets the first row of data, and then when it goes to 1 it assigns the next row of data to 1 and goes until the rows stop?

Thanks

1 Like

Yup. It gets the first element/row in data which is indexed by the number 0. Once that’s finished, it’ll move on to the next row in data which is indexed by the number 1. And so forth.

One thing to make clear is the index variable is different than the index used internally by the for loop. In other words, the for loop can function without it.

index, the variable, is not necessary in all situations. For example, you actually don’t need the index if all you want is to print things:

for row in data:
     print(row)

But it gets tricky without index because the for loop doesn’t provide us with the index it’s using:

for row in data:
     data[index] = row[:-1] 
     # how do we get the index the for loop is using in this case?

One method as you’ve seen is to create a variable called index (or whatever name you want) that keeps track of the index the for loop is currently using.

Another method is to tell the for loop to provide the index it’s using. One way to do this is to use enumerate which gives us both the index and the row:

for index, row in enumerate(data):
    data[index] = row[:-1]

It can be a lot to take in, so don’t worry if you don’t get it all right away.

Feel free to ask if you need any more help.

3 Likes

Hi, thanks again for another great explanation. It all makes sense and I understand what’s happening :slightly_smiling_face:.

1 Like