Question about for loops

Hello, I think this is a very simple question but I am bit stumped around my understanding of for loops. In the following code:

apps _data = [[‘Call of Duty: Zombies’, 5.0], [‘Facebook’, 0.0], [‘Instagram’, 0.0], [‘Temple Run’, 0.0]]

for app in apps_data:
price = app[1]

if price == 0.0:
    app.append('free')
if price != 0.0:
    app.append('non-free')

print(apps_data)

My understanding is that app is the iteration variable, it takes on the value of the first element of apps_data then runs the rest of the loop. In this case we indicate which element is price then tell the computer that if price is equal to 0 append “free” to app (which is the first element of apps_data right now) and if price does not equal 0 append “non-free” to app. Then the loop resets, and app takes on the next element of apps_data.

To me this code would append free to the variable app which during the first iteration would be the first element of apps_data. Then when the first iteration of the loop finishes, app is then replaced with the second list element of apps_data, until all the iterations are done. Meaning if we print apps_data at the end nothing will have changed and if we print app we will get the final element of apps_data with free appended to the list. However when we print apps_data, each element of apps_data has free or non-free appended to it. Does this mean that whatever changes you do to your iteration variable are then reflected into the iterable variable? The only reason I haven’t seen this happen yet is because we haven’t made changes to the iterable variable, just ran counts/comparison operators?

So really what is happening with a for loop is that we take the iteration variable and use it to store the first element of the iterable variable, at the end of the iteration whatever changes we made to the iteration variable are then put back into the iterable variable. Is this understanding correct? Sorry if this is too much text and I didn’t include code properly. This is my first post.

Thanks

@arvinabedi First, I want to say that this is a really great, sophisticated question! I think it demonstrates that you’re making really good progress learning, and thinking critically about what you’re doing. Awesome job! :tada:

Hopefully I can answer in a way that’s clear. :slightly_smiling_face:

So – this isn’t a “thing” about iterators, but rather something about lists. Take this example:

a_list = [1, 2]
another_list = a_list
another_list.append(5)
print(a_list)

This will print [1, 2, 5].

That’s because the internal representation of lists is not really the entire list itself, but rather a reference or pointer to someplace in the computer memory where the data is actually stored. So another_list = a_list just says to point to the same place in memory, and when you update it, the place where the data is stored doesn’t change – both a_list and another_list are still pointing to that same place in memory. But the contents in that place have been updated.

Note that I’m glossing a lot over details of the actual implementation of lists in Python, but the basic idea is accurate.

In Python (and in many programming languages), there are primitive types, and reference types. Primitive types are like int, float, bool, and variables of these types hold the real value of the data, whereas reference types are like list or dict, and variables of this type hold pointers to where the data lives in memory.

I hope I’ve helped, rather than confused the issue more! :slightly_smiling_face:

2 Likes

Lets first look at below logic :

app0 = ['Call of Duty: Zombies', 5.0]
app1 = ['Facebook', 0.0]
app2 = ['Instagram', 0.0]
app3 = ['Temple Run', 0.0]

apps_data = [app0,app1,app2,app3]
print(apps_data)
#[['Call of Duty: Zombies', 5.0], ['Facebook', 0.0], ['Instagram', 0.0], ['Temple Run', 0.0]]
print( )

app0.append('non-free') #app0 = apps_data[0] hence app0.append('non-free') = apps_data[0].append('non-free')
app1.append('free')
app2.append('free')
app3.append('free')
print(apps_data)
#above we appended a value to each of the lists that form apps_data hence  apps_data now = [['Call of Duty: Zombies', 5.0, 'non-free'], ['Facebook', 0.0, 'free'], ['Instagram', 0.0, 'free'], ['Temple Run', 0.0, 'free']]

As you see above, we first created 4 lists named app0, app1 etc and created another list apps_data with references to the individual lists app0, app1 etc. Now apps_data[0] = app0 , apps_data[1] = app1 and so on. So then appending a value to app0 list is same as appending a value to the 0th list element of apps_data (apps_data[0]) , appending a value to app1 list is same as appending a value to the 1st list element of apps_data (apps_data[1]) etc.

Now with above understanding about variable references, look at your for loop:
Basically for each list element (app) in the list of list apps_data, you are appending ‘free’ or ‘non-free’ based on whether price of each app is 0 or not. Hence the app variable in your for loop is a reference variable. As the loop iterates, the app variable refers to next element in apps_data.

So after appending to element for first iteration app = apps_data[0] = [‘Call of Duty: Zombies’, 5.0, ‘non-free’] , after appending to element for 2nd iteration app = apps_data[1] = [‘Facebook’, 0.0, ‘free’] and so on.

Hope now you are able to understand reference variables and why your loop is correctly behaving the way it is.

3 Likes

Hi Darla,

Thank you so much for clarifying this. You really got to the heart of my question because if you asked me what print(a_list) was going to print I 100% would have said [1,2]. I now understand that I should view these more as references/pointers to the same place in memory rather than individual objects.

Thanks so much!

1 Like