8/15 : i want use .remove() for the challenge


#1

<Below this line, add a link to the EXACT exercise that you are stuck at.>

https://www.codecademy.com/courses/learn-python/lessons/practice-makes-perfect/exercises/antivowel?action=lesson_resume

<In what way does your code behave incorrectly? Include ALL error messages.>

when i ==v and he is removed the next item take his place and the process go to the next step : compare the next “Box” of the tab. So the (i+1)-th item placed in the i-th Box is ignored.

I try to use a “while” instead of “if” but i get anothers issues so i came back to “if” for the moment

<What do you expect to happen instead?>

i want the (i+1)-th item placed in the i-th Box after the i-th item was remove to be compared before moving on to the next analysis of the next Box


def join_strings(tab): #function for concatenate c in tab2
  result = ""
  for c in tab:
    result +=  c
  return result

def anti_vowel(text):
  vowel = ['a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U']
  tab = []
  for c in text:
    tab.append(c)
  print tab, ": tab input" #Work well

  for v in vowel:
    print " "
    print v, ": the vowel compared"
    for i in tab:
      print "-",i, "is compared to", v
      if i == v:
        tab.remove(i)
        print "  ->", i, "is removed"
    
  print tab, ": tab output" #mistake in the tab due to .remove()
  return join_strings(tab) 


print anti_vowel("aAaaAaaaAGGWP")

print : aaAGGWP (i know why a, a and A was print, but is an another story to not print them) x)


#2

this problem only occurs when you remove from the same list as you are looping over.

Given we have both a string and a list of the string we want to remove the vowels, this problem is solvable.


#3

i found the solution : dont read the tab tab[0] to tab[len-1] but tab[len-1] to tab[0].
In this order i dont have the issue when a vowel is remove because i know the caractere which take the place of the removed vowel can’t be a vowel because i already check it ^^

i go code this ! ^^


#4

looping over the string in reverse and removing based on index is the other good solution

what i suggested was looping over the string while removing from the list, then problem also doesn’t occur given you are not removing from the element you are iterating


#5

ok its noticed :wink:

index = len(text)-1

for v in vowel:
    if tab[index] == v:
      tab.remove(tab[index]) #i think the pb is here with  "tab[index"] in ".remove()"
      index -= 1

i try to read in reverse but nothing is revomed :confused:


#6

to make looping in reverse work, you need to delete based on index, for which you need del. The remove() function removes the first match it can find, ignoring all the precious effort you put in looping in reverse


#7

BTW your method work (looping over string) :

for c in text:
    for v in vowel:
      if c == v:
        tab.remove(c)



#8

del dont work :c (or i use it bad) :

for v in vowel:
    if tab[index] == v:
      del tab[index]
    index -= 1

#9

i know, but do you also understand why?

del works fine, can i see the whole code with del? its seems you made a mistake somewhere


#10

of course i understand why it’s work … :slight_smile:zqefk jbhvd<hdqvBVdHBILSBhuBUsjbkBSbojmqosmMJKBSJB

(fuking smiley … i can’t press “enter” after “:” without it put a F*king smiley …

we remove nothing from the string “text” so the next caractere we check is at his good place and in the tab it remove the first occure of the caractere so nevermind if it take the place of the previous caractere removed ^^


#11

def join_strings(tab): #function for concatenate c in tab2
  result = ""
  for c in tab:
    result +=  c
  return result


def anti_vowel(text):
  vowel = ['a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U']
  
  tab = []
  #v = len(texte)-1
  index = len(text)-1
  
  for c in text:
    tab.append(c)
  print tab, ": tab input" #Work well
    
  for v in vowel:
    for r in range(len(text)-1, -1, -1):
      print r, ": r"
      if v == tab[r]:
        del tab[r]
      
    
    
  print tab, ": tab output" 
  return join_strings(tab) 


print anti_vowel("aAaaAaaaAGGWP")


#12

the use of the double loop seems to cause problem with the indexes, why not simple check if tab[r] in v? Its much easier. Or swap the loops at least, so this index error does not occur


#13

i get it !!! : (space before press enter)

for r in range(len(text)-1, -1, -1):
    print " "
    print tab[r], ": caractere compared"
    for v in vowel:
      
      print " ", tab[r], "is compare to", v
      if tab[r] in v:
        del tab[r]
        print "  ->", v, "was removed"

#14

Actually. No. You don’t want to use list.remove (not after thinking about what it does, which you should do for anything you use)

It’ll start at the beginning, compare each element to your value, and when it’s found, remove that value, but it’s still not done, because all the following values have to be moved one step to cover the gap.

With 100 elements, doing that 100 times and you have on the order of 10000 operations (5000 actually, 100 * average length which will be 50). You would not do it this way manually, the computer shouldn’t either.

del mylist[i] has the same issue, it won’t have to do the searching part since the index is known, but it still has to do the scooting over afterwards to cover the removed element.

And you don’t really want to go backwards either. First of all because you’re still not rid of the issue above, and second because it’s just plain complicated.

Often, it’s good to consider how you’d do it manually. The computer usually shouldn’t do it any differently, unless it can do something more efficient in a way we can’t.

How would we do it? We’d start a new list and only copy over the things to keep.


#15

why not? Yes, this approach has a huge disadvantage, and @seb16120 understand this. But by trying to find solution which works which involves remove, you really deepen your understanding, this is what seb16120 is doing, looking a the topics he created

yes, you shouldn’t implement remove into an actual solution, but for learning purposes, its actually really good


#16

It’s kind of like eval to read integers

It does so much more than the desired action, I’d rather switch over to linked list or something where removing an element is actually sensible. That, or do something which is sensible in the context of consecutive memory (one value after another in memory, with fixed positions)


#17

def anti_vowel(text):
  vowel = "aAeEiIoOuU"
  tab =[]
  for c in text:
    if c not in vowel:
      tab.append(n)
  
  return "".join(tab)

Happy ?

Now i go sleep. (i had taiso and jujistu today (yersteday because 1:00 a.m here) from 19h15 to 22h00 so i('m?) feel weak / tired / asleep and tomorraw (today) i have judo at 20h00)

See you next time (this afternoon)


#18

Yeah. Cause that no longer modifies something already in use elsewhere, and it avoids indexes which is another source of bugs, and unlike the other versions, you could run this on a really long book and it would finish in seconds instead of what would be hours or worse. (You could try this with a very large text file)

It uses an undefined variable so it’ll crash. But it’s mostly right.

Your del version also has a bug. It’ll crash if the input ends with a vowel.
I blame the backwards looping, reading and modifying the same value, direct use of indexes. It’s complicated code.


#19

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