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 trial
Iskander Ismagilov
13,298 PointsCombo challenge: my code works in workspaces but not in challenge
I got from forum that this challenge should be solved like this:
def combo(my_list, my_string):
new_list = []
for index, item in enumerate(my_list):
tup = item, my_string[index]
new_list.append(tup)
return new_list
But I didn't pay needed attention to enumerate func and solved it with more difficult code:
def combo(my_list, my_string):
if len(my_list) == len(my_string):
new_list = []
count = 0
for item in my_string:
my_list.append(item)
while True:
new_list.append(tuple(my_list[count::len(my_string)]))
count += 1
if count == len(my_string):
break
print(new_list)
but it works only in workspaces and not in challenge. It says: "Didn't get the right output. For example, expected (10, 'T') as the first item, got (10, 'T') instead." Why? I overthinked the code to get it solved, so if anybody knows I will appreciate an answer.
p.s: also appriciate for any feedback of my code
2 Answers
Chris Freeman
Treehouse Moderator 68,468 PointsYou are not crazy: your code returns the correct list of tuples results... but with side-effects.
By using the statement my_list.append() the code is modifying one of the input parameters. It is rarely a good practice to modify an input unless that is the purpose of the function. Python passes arguments by reference so my_list is equivalent to the global list passed in.
One fix for your code would be to operate on a copy of my_list:
def combo(my_list, my_string):
if len(my_list) == len(my_string):
new_list = []
my_list_copy = my_list[:] #<-- make a copy
count = 0
for item in my_string:
my_list_copy.append(item) #<-- operate on copy
while True:
new_list.append(tuple(my_list_copy[count::len(my_string)]))
count += 1
if count == len(my_string):
break
return new_list
How I would improve your code:
def combo(my_list, my_string):
# commented out conditional init. Challenge assumes equal length
#if len(my_list) == len(my_string):
# new_list = []
new_list = []
my_list_copy = my_list[:] #<-- make a copy
for item in my_string:
my_list_copy.append(item) #<-- operate on copy
# replace 'while True / count / break' with 'for range'
# count = 0
# while True:
for count in range(len(my_string)):
new_list.append(tuple(my_list_copy[count::len(my_string)]))
# count += 1
# if count == len(my_string):
# break
return new_list
Ultimately, the challenge can be solved without loops by using zip:
def combo(my_list, my_string):
new_list = list(zip(my_list, my_string))
return new_list
Iskander Ismagilov
13,298 PointsThank's Chris. Using a 'for range' loop is a nice idea, I have not thought about this before. This is why I should get into basics of python more carefully and find out what exactly iterables and iterators are and how they can be used with loops. And thank's a lot about 'side-effects', now I know more how to handle with arguments , if they vary inside of a function.
Chris Freeman
Treehouse Moderator 68,468 PointsChris Freeman
Treehouse Moderator 68,468 PointsKenneth Love, the OP code produced the correct return value, but failed due to modifying an input parameter. Can the error message be improved to indicate this is why the code is failing? The current message "Didn't get the right output. For example, expected (10, 'T') as the first item, got (10, 'T') instead." implies it's an output problem instead of a side-effect issue.