Yet another, remove_duplicates, where it works but returns an error


#1



https://www.codecademy.com/en/courses/python-intermediate-en-rCQKw/2/4?curriculum_id=4f89dab3d788890003000096#


After first getting over the hurdle of duplicate_list = original_list makes a link to the original NOT a copy I managed to get my code to run but now it produces the error message that I've tagged on the bottom of the code. It obviously refers to the 0th item in a list but all the obvious my_list[0]s seem to be filled with 'cheese' apart from in the original which is has 'goat' as it's [0] (checked using print statements).


I've been at this for at least an hour and I'm all out of ideas. Any enlightenment would be most welcome.


def remove_duplicates(goats):
    #work_list = in_list #original list copied to workg version
    work_list = []
    
    for x in goats: #copy input list to a copy That will not affect original
        work_list.append(x)
   
    work_list.sort() #sorted so duplicates will be next to each other
    result_list = [] 
    result_list.append(work_list[0]) #add the first item from the list
    last_item = work_list[0] #last item added from the original (sorted) list

    for item in work_list: #iterate through all items in sorted list
        if last_item != item: #if the current item is not the same as the previous item added to the output list
            result_list.append(item) #then add current item to output list
            last_item = item #and update the last item addded variable
    print "-".join(result_list)
    return result_list #give function a value

findem = ["goat", "cheese", "fish", "goat", "lemon", "pod", "flower", "goat", "polish"]
new_list = remove_duplicates(findem)
print "> <".join(new_list),
print ">"

""" OUTPUT (using copy and paste): 
cheese-fish-flower-goat-lemon-pod-polish
cheese> <fish> <flower> <goat> <lemon> <pod> <polish >
None
"""

""" ERROR MSG: Oops, try again. remove_duplicates([4, 5, 5, 4]) resulted in an error: sequence item 0: expected string, int found """


#2

Don't you just need to return a list that contains no duplicates?
Why are you joining a list to make it not a list?
Shouldn't it just be return result_list? Why is there a print statement in the function? Print statements only display content to the console but not necessarily output anything from the function.

tl:dr you don't need print "-".join(result_list)

edit: I noticed something else. You seem to have missed the fact that...what happens when your list is empty ([])?
To not alter your code a lot, i'd just suggest making an if statement in the beginning like this:

def remove_duplicates(goats):
    if goats == []:
        return goats
    else:
        #rest of your code with proper indentation

#3

Thanks for looking datfatcat.

If you look at the comments where is says OUTPUT you can see that that is what it does.

For display/debug purposes only. The data is still a list.

Debug still. To show that the function is giving a valid result just before exit.

This is just an exercise. For this example the data is written into the supporting program so it will never be empty. However, I just modified the code to read:

def remove_duplicates(goats):
    work_list = []
    if goats == work_list:
        return "No input found"

(without the else: branch there is no need to change the indentation)
and the call to read:

banana = []
new_list = remove_duplicates(banana)

as a test for an empty list in case the website is testing for this, but the error still persists even though the output was

N> <o> < > <i> <n> <p> <u> <t> < > <f> <o> <u> <n> <d >
None

#4

No. It is always best practice to consider a list to have a possibility of being empty. AND you need to RETURN the empty list if it is. Not some string.
I know because I've used your code in my environment and did exactly as I told you and it passed.

It's messing up the SCT. You're getting the error because of print "-".join(result_list). I've removed it and stopped getting the error (plus all the other things that were used for debugging purposes). It is because that print statement is inside the function. It affects things.

If you truly want to debug this, just simply put

findem = ["goat", "cheese", "fish", "goat", "lemon", "pod", "flower", "goat", "polish"]
print remove_duplicates(findem)

Then you'll see exactly what it is outputting (as you need to output a LIST of items without duplicates (see instructions)). And a list is in the form of this

findem = ["goat", "cheese", "fish", "goat", "lemon", "pod", "flower", "goat", "polish"]

and not what you are outputting.


#5

Hi. datfatcat,

Well that told me :blush: You were right about the empty list test.

I left in the empty list test but modified it to return an empty list instead of a string and it ran perfectly.

So it looks like, for this test, the website does test it against an empty list (as the error reappeared when I commented out the [] test.

So there were 3 gotchas I ran into when completing this exercise:

  • copy_list = original_list does NOT make a copy of a list. It just gives original_list the alias copy_list
  • As well as testing my function against the list I gave it, it also tested it against the empty list [] (as well as its own valid list of [4, 5, 5, 4] )
  • A list is expected as output (even when the input is [])

Thanks again for saving the rest of my hair from being pulled out datfatcat :slight_smile:. I can move on now.


#6

Glad it worked. This is how I did mine:


#7

That is a really nice, compact solution. I wrote mine before looking at the hint so did not use the not in form of the if.


#8

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.