Velocity Reviews > Re: substitution

# Re: substitution

Peter Otten
Guest
Posts: n/a

 01-18-2010
superpollo wrote:

> superpollo ha scritto:
>> hi.
>>
>> what is the most pythonic way to substitute substrings?
>>
>> eg: i want to apply:
>>
>> foo --> bar
>> baz --> quux
>> quuux --> foo
>>
>> so that:
>>
>> fooxxxbazyyyquuux --> barxxxquuxyyyfoo
>>
>> bye

>
> i explain better:
>
> say the subs are:
>
> quuux --> foo
> foo --> bar
> baz --> quux
>
> then i cannot apply the subs in sequence (say, .replace() in a loop),
> otherwise:
>
> fooxxxbazyyyquuux --> fooxxxbazyyyfoo --> barxxxbazyyybar -->
> barxxxquuxyyybar
>
> not as intended...

If you want to avoid regular expressions:

def replace_many(s, pairs):
if len(pairs):
a, b = pairs[0]
rest = pairs[1:]
return b.join(replace_many(t, rest) for t in s.split(a))
else:
return s

assert replace_many("abc", ["ab", "bc", "ca"]) == "bca"
assert (replace_many("fooxxxbazyyyquuux",
[("quuux", "foo"), ("foo", "bar"), ("baz", "quux")])
== "barxxxquuxyyyfoo")

Not tested.

Peter

Wyrmskull
Guest
Posts: n/a

 01-19-2010

Peter Otten wrote:

def replace_many(s, pairs):
if len(pairs):
a, b = pairs[0]
rest = pairs[1:]
return b.join(replace_many(t, rest) for t in s.split(a))
else:
return s

-------------

Proves wrong, this way x -> y -> z.
You call replace_many again on the central part of the split
Specifics indicate that x -> y in the end.
Your flowing pythonicity (if len(x) gave me lots of inspiration.
I bet this will win the prize

-------------

def mySubst(reps,string):
if not(len(reps)):
return string
a,b,c = string.partition(reps[0][0])
if b:
return mySubst(reps,a) + reps[0][1] + mySubst (reps,c)
else:
return mySubst(reps[1:],string)

print mySubst( ( ('foo','bar'), ('bar','qux'), ('qux','foo') ), 'foobarquxfoo')

-------
Wyrmskull <(E-Mail Removed)>

Peter Otten
Guest
Posts: n/a

 01-19-2010
Wyrmskull wrote:

> Peter Otten wrote:

>> def replace_many(s, pairs):
>> if len(pairs):
>> a, b = pairs[0]
>> rest = pairs[1:]
>> return b.join(replace_many(t, rest) for t in s.split(a))
>> else:
>> return s

> Proves wrong, this way x -> y -> z.
> You call replace_many again on the central part of the split
> Specifics indicate that x -> y in the end.

Sorry, I don't understand what you want to say with the above.

> Try with this:
>
> def mySubst(reps,string):
> if not(len(reps)):
> return string
> current = reps[0][0]
> a,b,c = string.partition(current)
> if b:
> return mySubst(reps,a) + reps[0][1] + mySubst (reps,c)
> else:
> return mySubst(reps[1:],string)
>
> print mySubst( ( ('foo','bar'), ('bar','qux'), ('qux','foo') ),
> 'foobarquxfoo')
>
> -------
> Wyrmskull <(E-Mail Removed)>

I don't see at first glance where the results of replace_many() and
mySubst() differ. Perhaps you could give an example?

Peter

PS: Please keep the conversation on-list

Peter Otten
Guest
Posts: n/a

 01-19-2010
Wyrmskull wrote:

> Your flowing pythonicity (if len(x) gave me lots of inspiration.

if len(pairs): ...

that should have been just

if pairs: ...

When I started writing the function I initially wanted to special-case
len(pairs) == 1. The len() call is a superfluous leftover.

Peter

Wyrmskull
Guest
Posts: n/a

 01-19-2010
Nvm, my bad, I misunderstood the split instruction.
No difference

-------
Wyrmskull

P.S Sorry about the P.M., I misclicked on a GUI