views:

68

answers:

3

I implemented a version of the str_replace function available in php using python. Here is my original code that didn't work

def replacer(items,str,repl):
    return "".join(map(lambda x:repl if x in items else x,str))

test = "hello world"
print test
test = replacer(test,['e','l','o'],'?')
print test

but this prints out

hello world
???

the code i got to do as expected is

def replacer(str,items,repl):
    x = "".join(map(lambda x:repl if x in items else x,str))
    return x

test = "hello world"
print test
test = replacer(test,['e','l','o'],'?')
print test

which prints out

 hello world
 h???? w?r?d

just like I wanted it to.

Aside from the fact that there is probably a way using builtins that i haven't seen yet, why does the first way fail and the second way do what I need it to?

+1  A: 

You're passing it in backwards in the first one. It should be should be

test = replacer(['e','l','o'], test, '?')
Matthew Flaschen
+4  A: 

The ordering of the arguments to replacer is what makes the difference between the two. If you changed the argument ordering in the first version it'd behave like the second version.

Jeff Walden
+3  A: 

Don't use built-in names such as str for your own identifiers, that's just asking for trouble and has no benefit whatsoever.

Apart from that, your first version is looping on str, the second argument -- the list ['e', 'l', 'o'] -- so of course it will return a string of exactly three items -- how could you expect it to return a string of any other length?! Using str to name a list argument is particularly perverse and bug-prone.

The second version loops on str, the first argument -- the string 'hello world' so of course it's returning a string of that length.

Alex Martelli
i know it was just a quick example i was trying to show one of my friends who does a lot of php
controlfreak123
is there a way to do multiple replacement like this with the builtin string methods or is a small piece of code like this what I need each time?
controlfreak123
@controlfreak, the `.translate` method of strings is much better (but for bytestrings in Python `2.*` you have to prep a translate table with `string.maketrans` first -- Unicode objects, and Python 3 strings which are also unicode, are neater as they take a `dict`).
Alex Martelli
@Alex: very cool thank you!
controlfreak123