0

I have a list of punctuation that I want the loop to remove from a user inputted sentence, and it seems to ignore multiple punctuation in a row?

punctuation = ['(', ')', '?', ':', ';', ',', '.', '!', '/', '"', "'"]
usr_str=input('Type in a line of text: ')

#Convert to list
usr_list= list(usr_str)

#Checks if each item in list is punctuation, and removes ones that are
for char in usr_list:
    if char in punctuation:
        usr_list.remove(char)

#Prints resulting string
print(''.join(usr_list))

Now this works for:

This is an example string, which works fine!

Which prints:

This is an example string which works fine

However, something like this:

Testing!!!!, )

Gives:

Testing!!

Thanks in advance for the help!

Stensby
  • 3
  • 1
  • 2
  • The problem is that the iterator isn't being moved back to check the character that takes the place of the one removed. However, you really should be using a cleaner approach such as a RegEx. – Spencer Ruport Oct 18 '13 at 02:19
  • Ah okay Spencer that makes sense, and I am reasonably new at Python, so I will do some looking into Regular Expressions. Thanks! – Stensby Oct 18 '13 at 02:22
  • If you don't want to get into a RegEx I'd also recommend @Soon's answer for `string.translate`. – Spencer Ruport Oct 18 '13 at 20:36
  • See [Loop “Forgets” to Remove Some Items](http://stackoverflow.com/q/17299581/1730674) also [str.replace issue](http://stackoverflow.com/q/15456639/1730674) and [Remove specific characters from a string](http://stackoverflow.com/q/19458344/1730674) – askewchan Oct 18 '13 at 20:41

2 Answers2

2

You're changing the list while you're iterating over it. Never a good idea.

One way to get it to work is to iterate over a copy of the list:

for char in usr_list[:]:  # this is the only part that changed; add [:] to make a copy
    if char in punctuation:
        usr_list.remove(char)

With more experience, you'll probably use a "list comprehension" instead:

usr_list = [char for char in usr_list if char not in punctuation]

You'll probably get other answers using filter() or regular expressions or ... too. But keep it simple at first :-)

Another way is to make two different lists. Say your input list is input_list. Then:

no_punc = []
for char in usr_list:
    if char not in punctuation:
        no_punc.append(char)

And note that there's really no need to use an input list in this way either. You could iterate directly over your usr_str instead.

Tim Peters
  • 67,464
  • 13
  • 126
  • 132
  • Thanks so much Tim, this seems like a straightforward fix, and I understand both ways. My assignment specifies using a loop, so the first way will have to be what I use, but its nice to know there are simpler ways! – Stensby Oct 18 '13 at 02:26
  • Using `[:]` may be too obscure, though, so I just added another way - it will be even more obvious to you ;-) And added another way getting rid of one of the lists. – Tim Peters Oct 18 '13 at 02:30
2

This could be done using str.translate method:

In [10]: 'Testing!!!!, )'.translate(str.maketrans('', '', string.punctuation))
Out[10]: 'Testing '
awesoon
  • 32,469
  • 11
  • 74
  • 99