user3413477
user3413477

Reputation: 11

Filtering characters from a string in python. (if the characters are in string2, filter them from string1)

I've been having a syntax issue with this code. I get a syntax error on the if statement line. The purpose of this code is to filter out the characters from string 2, and reprint string 1 without them. I think my logic is correct in how I've written it out (for loop to check if the character is in both strings, and then an if statement to filter out those characters from string2). But I'm really crappy so I probably did something wrong.

def filter_string(str1, str2):
    newstr = ""

    for c in str1 and str2:
        if c == str1 and != str2:
            newstr += newstr + c
            break
    return newstr

Thanks for the help!

Upvotes: 1

Views: 2091

Answers (4)

J Bryde
J Bryde

Reputation: 1

Certainly there are multiple ways to do this. Personally this is the simplest logic to folow:

def filter_string(str1, str2):
    str3=''
    for c in str1:
        if c not in str2:
        str3+=c
    return (str3)

Upvotes: 0

Hbrewitt
Hbrewitt

Reputation: 28

If you want something very similar to your first attempt, this will work:

def filter_string(str1, str2):
newstr = ''
for c in str1: 
    if c not in str2:
        print c
        newstr += c

return newstr

Upvotes: 1

Aaron Hall
Aaron Hall

Reputation: 394995

Here's how I'd do it in Python 2:

def filter_string(s, remove):
    '''given a string, s, remove characters in string, remove'''
    return s.translate(None, remove)

If you're in Python 3:

def filter_string(s, remove):
    return s.translate(str.maketrans('','',remove))

Or if you want compatibility across Python versions:

import re
def filter_string(s, remove):
    return re.sub('[' + remove + ']', '', s)

Either way, here's usage:

>>> filter_string('foo (*& bar', '&(*')
'foo  bar'

Here's timing, for Python 3 on my machine:

import timeit

setup = """
def filter_string_1(s, remove):
    return s.translate(str.maketrans('','',remove))

import re
def filter_string_2(s, remove):
    return re.sub('[' + remove + ']', '', s)
"""

timeit.timeit("filter_string_1('foo (*& bar', '&(*')", setup)
timeit.timeit("filter_string_2('foo (*& bar', '&(*')", setup)

For me returns:

1.6555187609919813
2.7981851549993735

So translate is even faster than regex for this trivial example.

Upvotes: 4

James Mills
James Mills

Reputation: 19030

Sticking fairly closly to your initial attempt:

def filter_string(s, remove):
    result = []

    for c in s:
        if c not in remove:
            result.append(c)

    return "".join(result)

print filter_string("foo (*& bar", "(*&)")

Note: This isn't terribly very efficient as you're creating a list to store a list of characters of the new string that don't match the remove iterable and finally returning a new string by joining the result list with an empty string.

A better approach is to simply use the str.translate() method:

>>> "foo (*& bar".translate(None, "(*&)")
'foo  bar'

Here's some performance comparisions between the two approaches:

$ python -m timeit -s "from foo import filter_string" "filter_string('foo (*& bar', '(&*)')"
foo  bar
100000 loops, best of 3: 2.32 usec per loop

$ python -m timeit "'foo (*& bar'.translate(None, '(*&)')"
1000000 loops, best of 3: 0.265 usec per loop

The later approach is approximately 10x faster.

Upvotes: 0

Related Questions