Python Introducing Lists Using Lists Review Mutability

Anthony Lopez
Anthony Lopez
963 Points

Copy of a copy?

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

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

dinner_options = tacos_only(all_restaurants)

Hey I had a question about this code. It looks like it is looping through a copy of a copy. The code has already made a copy of the restaurants (restaurants.copy()). Why do you then need to make another copy of taco_joints?

Thanks!

Bonus question: Could I have replaced if "taco" not in taco_joints.lower(): with if taco_joints.lower() == "taco":?

1 Answer

andren
andren
28,450 Points

Hey I had a question about this code. It looks like it is looping through a copy of a copy. The code has already made a copy of the restaurants (restaurants.copy()). Why do you then need to make another copy of taco_joints?

It is indeed a bit unusual to copy a copy, and honestly it might just have been an oversight, but one purpose I can think of for looping through a copy of a copy is to make sure the function does not make permanent changes to what was passed into it. With the way the function is setup it takes one list (all_resturants) and then uses that as a basis to create a new list with only taco restaurants in it.

If you remove the first copy operation then you would be modifying the all_resturants directly so that after the function ran it would have not only created a new list, but also modified the all_resturants list that was passed in. Since the function is setup to generate a new list modifying the list passed into it as well is a tad counter-intuitive.

So basically the first copy is to make it so you can modify the list without affecting the list that was passed into the function (all_resturants) while the second copy is there to make sure the loop does not break while you are modifying this new copy. There are other ways of achieving this which does not result in copying twice but the function as it stands is pretty simple and easy to read which might be why it was written that way.

Bonus question: Could I have replaced if "taco" not in taco_joints.lower(): with if taco_joints.lower() == "taco":?

No you could not. The in keyword essentially asks Python if one string can be found somewhere inside the other string. The == operator on the other hand tells Python to check if the two strings store the exact same value. Meaning that it would only evaluate to true if the restaurant was literally called taco and nothing else. Since the restaurants contain the word taco but also contain other words like City, villa, etc they would not be an exact match.

Also since the original code checks that taco is not included in the restaurant name your code would have reversed the logic, since you use == (equals) instead of != (not equals). But regardless of which you use it would not have worked the same since both of those look for exact matches.

Anthony Lopez
Anthony Lopez
963 Points

Thank you! Great answer.