Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialtimoleodilo
1,438 Pointsthis code its to confusing
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)
3 Answers
Viraj Deshaval
4,874 PointsOk let me explain you bit by bit.
How it works is as below:
# Step - 1: Variable 'all_restaurants' is created with list of restaurant names. This is straight forward.
all_restaurants = [
"Taco City",
"Burgertown",
"Tacovilla",
"Hotdog station",
"House of tacos",
]
# Step - 2: Defined a function name 'tacos_only' and passed a single argument to the function 'all_restaurants' in function parameter 'restaurants'.
def tacos_only(restaurants):
# Step - 3: Confusing part is here, so what we need to do now is we want to remove the restaurants from the
# 'all_restaurants' list by using the '.remove()' method. If I try to remove the restaurants from the all_restaurants list by iterating through each element then indexing gets changed. see below how it works:
# What I did is I have added the "Mc Donalds' at index 1. See how it works without copy as below
all_restaurants = [
"Taco City", # index: 0
"Mc Donalds", # index: 1
"Burgertown", # index: 2
"Tacovilla", # index: 3
"Hotdog station", # index: 4
"House of tacos", # index: 5
]
# I will run a for loop to loop over all the element in the list so now
Iteration - 1: At index = 0
taco_joint = "Taco City"
if "taco" not in taco_joint.lower():
all_restaurants.remove(taco_joint)
It found taco in the string "Taco City" so it will not remove the string
Iteration - 2: At index = 1
taco_joint = "Mc Donalds"
if "taco" not in taco_joint.lower():
all_restaurants.remove(taco_joint)
Did'nt found "taco" in string "Mc Donalds" so remove the element "Mc Donalds" from index 1. So when it removed the "Mc Donalds" list element gets shifted so 'all_restaurants' looks like below:
all_restaurants = [
"Taco City", # index: 0
"Burgertown", # index: 1
"Tacovilla", # index: 2
"Hotdog station", # index: 3
"House of tacos", # index: 4
]
Iteration - 3: Now if I loop through the new all_restaurant list it will skip through the "Burgertown" resides at index 1. So it will never check the if condition for 'Burgertown'
at index 2
taco_joint = "Tacovilla"
for taco_joint in all_restaurants:
if "taco" not in taco_joint.lower():
all_restaurants.remove(taco_joint)
if found "taco" in string name "Tacovilla" so it was not remvoed.
O/p: ['Taco City', 'Burgertown', 'Tacovilla', 'House of tacos']
To resolve this, we create a 2 copy of the list "all_restaurants" and assigned it to variable "taco_joints"
1). First copy is to remove the element from the list
2). Second copy is to only iterating over the list
taco_joints = restaurants.copy() # this is the first copy from which we only remove the elements
for taco_joint in taco_joints.copy(): # this is the second copy from which we only loop over the elements
if "taco" not in taco_joint.lower():
taco_joints.remove(taco_joint)
return taco_joints
dinner_options = tacos_only(all_restaurants)
So how it works as below using copy:
all_restaurants = [
"Taco City", # index: 0
"Mc Donalds", # index: 1
"Burgertown", # index: 2
"Tacovilla", # index: 3
"Hotdog station", # index: 4
"House of tacos", # index: 5
]
taco_joints = all_restaurants.copy()
for taco_joint in taco_joints.copy():
if "taco" not in taco_joint.lower():
taco_joints.remove(taco_joint)
Iteration - 1: Loop over the second copy of the list
At index = 0
taco_joint = "Taco City"
if "taco" not in taco_joint.lower():
all_restaurants.remove(taco_joint)
It found taco in the string "Taco City" so it will not remove the string
Iteration - 2: Loop over the second copy of the list
At index = 1
taco_joint = "Mc Donalds"
if "taco" not in taco_joint.lower():
all_restaurants.remove(taco_joint)
Did'nt found "taco" in string "Mc Donalds" so remove the element "Mc Donalds" from index 1 from "taco_joints" list (first copy of the list). So when it removed the "Mc Donalds" list element gets shifted so 'taco_joints' looks like below:
taco_joints = [
"Taco City", # index: 0
"Burgertown", # index: 1
"Tacovilla", # index: 2
"Hotdog station", # index: 3
"House of tacos", # index: 4
]
Notice here second copy of the 'taco_joints' remain unchanged and no element shifted.
Iteration - 3: Loop over the second copy of the list
Now if I loop through the list 'taco_list.copy()' (second copy of the list) it will not skip through the "Burgertown" resides at index 1. So it will check the if condition for 'Burgertown'
at index 2
taco_joint = "Burgertown"
for taco_joint in all_restaurants:
if "taco" not in taco_joint.lower():
all_restaurants.remove(taco_joint)
No taco in Burgertown it will not remove
I hope this helps
timoleodilo
1,438 PointsHey Viraj. Thank you very much for this. is making more sense to me now. I was getting frustrated and could not understand it. once again Thank you.
Viraj im looking to buy a python book for begginers. What would you recommend. if you do. there are a lot of books out there Thanks in advance.
timoleodilo
1,438 PointsHey Viraj. Thank you very much for this. is making more sense to me now. I was getting frustrated and could not understand it. once again Thank you.
Steven Parker
231,271 PointsYou don't have to completely understand the sample program to answer the question. The question is about general loop issues.
A good rule to remember is to never modify an iterable inside the loop it is controlling, it can cause side effects.
John Lack-Wilson
8,181 PointsJohn Lack-Wilson
8,181 PointsHi Tim, could you be more specific about which part is causing the confusion?