My code works, but Codecademy won't accept it


#1



Remove Duplicates


My code works, but codecademy won't accept it. I wrote this not knowing that I can use "if not in" to remove the duplicates.


Again, my code outputs the correctly: no, duplicates. But this is what codecademy says:
Oops, try again. remove_duplicates([]) resulted in an error: list index out of range

Could someone please help me identify why I get what codecademy says above.


def remove_duplicates(the_list):
    
    selector = []# this list is for storing non-duplicates of the pivot
    pure_list = []#this is where the purified pivot's are stored
    pivot_count = 0 
    
    pivot = the_list[pivot_count] 
    
    #this is just so i can keep looping
    while  len(the_list) != 0:
        
        
        #this will loop through the size of the_list
        for i in range(len(the_list)):
            
            #compares the first entry to the every entry
            #if the same do nothing; if not the same, append
            if pivot != the_list[i]:
              
                selector.append(the_list[i])
                
        #his is to update the_list
        #updating the_list means getting rid of the pivot's duplicates
        the_list = selector
      
        selector = [] #this clears the selector the pivot's non_duplicates can be stored again
        
        pure_list.append(pivot)#adds the pivot that was purified to pure_list
        
        
        if pivot_count == len(the_list):#unfortunately, I don't know anyother way to stop my whil loop,but this
            break
        else:
            pivot = the_list[pivot_count]#pivot becomes the 1st item of the updated the_list
            
        

    return pure_list    
   

        
print remove_duplicates([5,5,2,5,5,5,23,5,3,2,23,6,6,6,6])


#2

This is the line that is raising the index out of range error. When the input list is empty, there is no index 0.

pivot = the_list[pivot_count]

Your code only returns a single item in the uniques list...

>>> remove_duplicates([5,5,2,5,5,5,23,5,3,2,23,6,6,6,6])
[5]
>>>

Consider that since we are creating a separate list of uniques, do we need an index at all?


>>> def remove_duplicates(s):
	r = []
	for n in s:
		if n not in r:
			r.append(n)
	return r

>>> remove_duplicates([5,5,2,5,5,5,23,5,3,2,23,6,6,6,6])
[5, 2, 23, 3, 6]
>>> remove_duplicates([])
[]
>>>

#3

Using the index, this version only took me about two hours and thirty some revisions...


>>> def remove_duplicates(s):
    i = 0
    while True:
        if i == len(s): break
        j = i + 1        
        while True:
            if j == len(s): break
            if s[j] == s[i]:
                s.pop(j)
            else: j += 1
        i += 1
    return s

>>> remove_duplicates([5,5,2,5,5,5,23,5,3,2,23,6,6,6,6])
[5, 2, 23, 3, 6]
>>> remove_duplicates([])
[]
>>> remove_duplicates(['one', 'two', 'three', 'one', 'two', 'three'])
['one', 'two', 'three']
>>>

Sorry, but I'm still trying to wrap my head around your code and the logic you used. Is the above anythnig close to what you had in mind?


#4

Still working on a decent answer, but wondering what the objective is. Maybe this is more what you are going for... A uniques list, and a list of the duplicated terms.


def remove_duplicates(s):
  if s.__class__.__name__ not in ('list', 'str', 'tuple'):
    return "Input Error!"
  f = 0
  if isinstance(s, str): s = s.split(); f = 1
  elif isinstance(s, tuple): s = list(s)
  u = []; i = 0
  while True:
    if i == len(s): break
    j = i + 1
    while True:
      if j == len(s): break
      if s[j] == s[i]: u.append(s.pop(j))
      else: j += 1
    i += 1
  return ' '.join(s) if f else s, set(u) if len(u) else u

print (remove_duplicates([]))    # ([], []])
print (remove_duplicates((5,5,2,5,5,5,23,5,3,2,23,6,6,6,6)))
# ([5, 2, 23, 3, 6], {2, 5, 6, 23})
print (remove_duplicates(['one', 'two', 'three', 'one', 'two', 'three']))
# (['one', 'two', 'three'], {'one', 'three', 'two'})
print (remove_duplicates('one two three one two three'))
# ('one two three', {'one', 'three', 'two'})
print (remove_duplicates({'one': 1, 'two': 2, 'three': 3}))     # Input Error!
print (remove_duplicates({5,5,2,5,5,5,23,5,3,2,23,6,6,6,6}))    # Input Error!

The first list is ordered, the second is not.

More proof of concept: https://repl.it/JLVS/0


#5

Here is pretty much exactly what @mifons wrote but as a working script:


def remove_duplicates(the_list):
    selector = [] # Same as your script, to store non-ducplicates
    iteration = 0 # This is there to break our while loop
    
    while iteration < len(the_list): # Same as your while loop, just to ensure the whole of the_list is iterated over
        pivot = the_list[0] # Sets pivot to be the first item in the_list, as the_list is always being rewriten with a new number at index[0] the 0 doesn't need to change.

        for comparison in the_list[1:]: # This is  doing what you wanted your for loop to do. It ignores the first item as it is the same as pivot and obviously will be the same.
            
            if pivot != comparison: #Same as your comparision

                selector.append(comparison) # Comparision is the same as your the_list[i]               
	    
	selector.append(pivot) #Because any item the same as pivot wouldn't have been appended to selector, we add it now and it will now be unique.
	the_list=selector # Same as yours
	selector=[] # Same as yours
	iteration+=1 # Plus one to iteration to stop the while loop being an infinite loop.
	
    return the_list # Returns the_list with duplicates deleted.

I've not tried to make it any more efficeint etc, just get it working. It just shows that he wasn't all that far off.


#6

Nicely done! The member will appreciate the hard work you put in to get his script up and running correctly, as do I.


#7

Thank you so much guys, especially to you @mtf :slightly_smiling_face:The script by @jagking is what I was going for, because as I've said, I did not know that I could use the "if not in" to remove the duplicates. I also don't know how to use .pop( ), .split ( ) and many more built-in functions that @mtf, yet.

Anyway, @mtf, I had a suspicion that it was pivot = the_list[pivot_count], but again, the script works because the editor skips it when the_list is empty. Regardless, codeacademy seem to catch on to it. It's not an efficient script, but I just wanted it to work. Again, you have my heartfelt thanks for your effort @mtf.

Lastly, @jagking, your script is very concise compare to what I was going for. Looking at it, I could see that its logic is flawless, but when I tried to run it in the codeacademy editor I get:
Traceback (most recent call last):
File "python", line 21, in
File "python", line 12, in remove_duplicates
MemoryError

Why is that?

Again thank you again guys :smile:


#8

It's strange that you get a MemoryError, this basically means it has run out of RAM. This code doing that would be a miracle, unless you inputted a stupidly large list. It works for me in codeacdaemy, so must have been one of those things. Try resetting the code and pasting it back in.

Lastly, @jagking, your script is very concise compare to what I was going for. Looking at it, I could see that its logic is flawless,

That is your logic and script for the most part. All I did was remove some of the extra stuff that became redundant and did a little reshuffle. The only real things you did wrong were how to handle the while loop (understandable you said you didn't know how to iterate over it and end it) and handling of the_list, selector and pure_list and you weren't miles off with them,. Seriously, that is over 90% you.

To prove it:

def remove_duplicates(the_list):
    selector = [] # Your code
    iteration = 0 
    
    while iteration < len(the_list): # Your logic, My code
        pivot = the_list[0] # Your logic adjusted slightly for my code

        for i in range(len(the_list)): # Your code
            
            if pivot != the_list[i]: #Your code

                selector.append(the_list[i]) # Your code               
	    
	selector.append(pivot) # Your code, just different list being appended to
	the_list=selector # Your code
	selector=[] # Your code
	iteration+=1 
	
    return the_list

See most of it is your code or logic...:clap::thumbsup: And not much was removed, honestly if I claimed that as my own I'm sure you would be able to sue me.:rofl:

You'll notice I put your code back in:

        for i in range(len(the_list)):
            if pivot != the_list[i]:              
                selector.append(the_list[i])

This was doing exaclty what I wrote was, only yours got to the memory address through the indexes. I only left the way I did it in before because I forgot to remove it and then didn't replace it because it is a little easier to read. But with your three lines in there instead it still works 100%.


#9
Code
# https://discuss.codecademy.com/t/my-code-works-but-codecademy-wont-accept-it/148450/7

def remove_duplicates(the_list):
    selector = []
    iteration = 0
    
    while iteration < len(the_list):
        pivot = the_list[0]

        for comparison in the_list[1:]:            
            if pivot != comparison:
                selector.append(comparison)
        
        selector.append(pivot)
        the_list = selector
        selector = []
        iteration += 1
	
    return the_list

print remove_duplicates([])
print (remove_duplicates((5,5,2,5,5,7,8,5,23,5,3,2,23,6,6,6,6)))

So basically the only difference between this and the one I came up with is that this replaces the list each pass, whereas mine is in place?

while iteration < len(the_list):

This line has be wondering (it has always been a question on my mind), does len(the_list) get updated on each while iteration? It doesn’t seem to in a for loop.


#10

Pretty much, yeah. As you say, you just remove duplicates from the list while @mifons way remakes the list without the duplicates each time.

It does get updated for the while loop, yes or rather I guess the correct way of looking at it is that the while loop does not load len(the_list) into memory but reruns it each time it does the boolean check.


#11

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