Python Introducing Lists Using Lists Review Mutability

Ivan Frances Alcantara
Ivan Frances Alcantara
4,280 Points

If restaurants.copy() creates a copy, why can't we use it directly as in "for taco_joint in restaurants.copy():"?

Isn't the code creating two copies?

3 Answers

adrian miranda
adrian miranda
11,468 Points

I'm not sure your question is clear. The following will work fine:

for taco_joint in restaurants.copy():

Perhaps you are asking, why can't you do it without the copy, like this?

for taco_joint in restaurants:

Usually, that would be fine. However, in this particular case it's a bad idea, because the code goes on to modify the list, removing certain elements. If you modify a list while you are iterating across it, the results are undefined. Think of it as trying to go up a staircase at the same time as someone else is removing some of the steps. Depending on the exact order things happen, you could hit a step just as it's removed and fall. Something similar can happen when you are modifying the list at the same time as you iterate across it.

Ivan Frances Alcantara
Ivan Frances Alcantara
4,280 Points

Thanks Adrian, I tried to write the code and it returned nothing, so I think I understand now the first copy is assigned to a value so that later on can be referrenced without creating more copies, and the second copy is for the for loop to work properly. Here is my try not understanding the taco_joints purpose:

all_restaurants = [ "Taco City", "Burgertown", "Tacovilla", "Hotdog station", "House of tacos", ]

def tacos_only(restaurants): for taco_joint in restaurants.copy(): if "taco" not in taco_joint.lower(): restaurants.copy().remove(taco_joint) return restaurants.copy()

dinner_options = tacos_only(all_restaurants)

adrian miranda
adrian miranda
11,468 Points

No, you only want to use the copy() once in this case, in the for loop.

For example, if you do:

restaurants.copy().remove(taco_joint)

That will first make a copy, then remove the taco_joint from that copy only. And at the end of the line, the copy goes away completely. You haven't modified anything that sticks around. Since your goal was to remove certain restaurants, that will not achieve your goal, because the original list hasn't been modified.

So, everything should use the original list (meaning, do NOT use copy()), except the for loop. The for loop needs to use a copy() so that the list it is using does not get changed while it is going over it. But nothing else in this function should be using a copy, because the rest of it actually wants to keep working on (and changing) the original.