0

Having a really silly problem. I'm iterating over a string and removing all non-alphabetical characters. The problem is that when I remove them, the length of the string decreases and my loop crashes because I go out of bounds.

for x in s:
    if x.isalpha() == False:
        s = s.replace(x, "")
2
  • 1
    What do you mean it crashes? You're not using indexing at all so there's no chance of it going out of bound. Commented Oct 24, 2014 at 4:56
  • If s really is a string, this will not crash, whatever that means. The code you posted will work and produce the intended result both on Python 2 and Python 3. It is however very inefficient. Commented Oct 24, 2014 at 8:38

4 Answers 4

3

Use filter!

s = filter(str.isalpha, s)
Sign up to request clarification or add additional context in comments.

2 Comments

This produces a list, not a string
@mhawke From docs: If iterable is a string or a tuple, the result also has that type; otherwise it is always a list. Though in Python 3 it returns an iterator so an extra str.join call will be needed.
2

Use a regex!

import re
regex = re.compile('[^a-zA-Z]') #Create a regex that allows on only A-Z and a-z
regex.sub('', s) #This will return the string, stripped of non alphabetical characters

2 Comments

I'd love to, but I'm helping a friend with an assignment and that'd be too advanced for his class. I gotta do it the simple way and my brain is farting.
Regex's shouldn't be too advanced, but any of the answers posted here will work - there's multiple ways to solve this - pick whatever you choose :)
1

The trick is to loop from end to front if you insist to use loop...

This is the useful trick to handle the length change.

for x in s[::-1]:
    if x.isalpha() == False:
        s = s.replace(x, "")

Edit: I forgot to mention, to reverse a string, you can do s[::-1]

2 Comments

Just adding that s[::-1] is a shortcut to reverse a string, in case you aren't sure why this solves your problem
And this is entirely unnecessary as the iterator created using the string at the start of the loop is independent of s, it will work even if you delete s.
0

A list comprehension is the most Pythonic way to do this.

s = ''.join([x for x in s if x.isalpha()])

The list comprehension builds a list containing alpha characters only, and join() returns a string of those characters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.