[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

alternating string replace

cesco

1/9/2008 10:34:00 AM

Hi,

say I have a string like the following:
s1 = 'hi_cat_bye_dog'
and I want to replace the even '_' with ':' and the odd '_' with ','
so that I get a new string like the following:
s2 = 'hi:cat,bye:dog'
Is there a common recipe to accomplish that? I can't come up with any
solution...

Thanks in advance
Cesco
36 Answers

cokofreedom

1/9/2008 10:41:00 AM

0

On Jan 9, 11:34 am, cesco <fd.calabr...@gmail.com> wrote:
> Hi,
>
> say I have a string like the following:
> s1 = 'hi_cat_bye_dog'
> and I want to replace the even '_' with ':' and the odd '_' with ','
> so that I get a new string like the following:
> s2 = 'hi:cat,bye:dog'
> Is there a common recipe to accomplish that? I can't come up with any
> solution...
>
> Thanks in advance
> Cesco

For replacing every other one, I tend to use the modulo, with a
counter.

count = (if u want even start with 0 else do 1)

while/for replacing /in lalastring:
if count % 2 == 0:
do even
else:
do odd
count += 1

This is a rather basic way of doing it, and I am sure people will sure
much more efficient ways, but it generally works for me.

Though I am now wondering if count % 2 when count == 2 is true or
false as it returns 0

Of course you still need to do your replace but you should be able to
do that.

Fredrik Lundh

1/9/2008 10:44:00 AM

0

cesco wrote:

> and I want to replace the even '_' with ':' and the odd '_' with ','
> so that I get a new string like the following:
> s2 = 'hi:cat,bye:dog'
> Is there a common recipe to accomplish that? I can't come up with any
> solution...

how about splitting on "_", joining pairs with ":", and finally joining
the result with "," ?

>>> s1 = "hi_cat_bye_dog"
>>> s1 = s1.split("_")
>>> s1
['hi', 'cat', 'bye', 'dog']
>>> s1 = [s1[i]+":"+s1[i+1] for i in range(0,len(s1),2)]
>>> s1
['hi:cat', 'bye:dog']
>>> s1 = ",".join(s1)
>>> s1
'hi:cat,bye:dog'

(there are many other ways to do it, but the above 3-liner is short and
straightforward. note the use of range() to step over every other item
in the list)

</F>

Peter Otten

1/9/2008 10:57:00 AM

0

cesco wrote:

> say I have a string like the following: s1 = 'hi_cat_bye_dog'
> and I want to replace the even '_' with ':' and the odd '_' with ',' so
> that I get a new string like the following: s2 = 'hi:cat,bye:dog'

>>> import re
>>> from itertools import cycle
>>> re.sub("_", lambda m, c=cycle(":,").next: c(), "hi_cat_bye_dog")
'hi:cat,bye:dog'

> Is there a common recipe to accomplish that? I can't come up with any
> solution...

There are many. If you want to learn Python don't be afraid to write it
in a long-winded way (with loops and helper functions) first.

Peter

Duncan Booth

1/9/2008 11:34:00 AM

0

cesco <fd.calabrese@gmail.com> wrote:

> Hi,
>
> say I have a string like the following:
> s1 = 'hi_cat_bye_dog'
> and I want to replace the even '_' with ':' and the odd '_' with ','
> so that I get a new string like the following:
> s2 = 'hi:cat,bye:dog'
> Is there a common recipe to accomplish that? I can't come up with any
> solution...
>
Here's yet another answer:

from itertools import islice, cycle

def interleave(*iterators):
iterators = [ iter(i) for i in iterators ]
while 1:
for i in iterators:
yield i.next()


def punctuate(s):
parts = s.split('_')
punctuation = islice(cycle(':,'), len(parts)-1)
return ''.join(interleave(parts, punctuation))

s1 = 'hi_cat_bye_dog'
print punctuate(s1)


# Or as a one-liner (once you have interleave):

print ''.join(list(interleave(s1.split('_'), cycle(':,')))[:-1])

Bearophile

1/9/2008 12:20:00 PM

0

My version, uses a re.sub, plus a function used as an object with a
one bit state:

from re import sub

def repl(o):
repl.n = not repl.n
return ":" if repl.n else ","
repl.n = False

print sub("_", repl, "hi_cat_bye_dog_foo_bar_red")

Bye,
bearophile

cokofreedom

1/9/2008 1:08:00 PM

0

Designed a pretty basic way that is "acceptable" on small strings.

evenOrOdd = True
s1 = "hi_cat_bye_dog_foo_bar_red"
s2 = ""

for i in s1:
if i == '_':
if evenOrOdd:
s2 += ':'
evenOrOdd = not evenOrOdd
else:
s2 += ','
evenOrOdd = not evenOrOdd
else:
s2 += i

print s2

Neil Cerutti

1/9/2008 1:42:00 PM

0

On Jan 9, 2008 5:34 AM, cesco <fd.calabrese@gmail.com> wrote:
> Hi,
>
> say I have a string like the following:
> s1 = 'hi_cat_bye_dog'
> and I want to replace the even '_' with ':' and the odd '_' with ','
> so that I get a new string like the following:
> s2 = 'hi:cat,bye:dog'
> Is there a common recipe to accomplish that? I can't come up with any
> solution...
>
> Thanks in advance

Hum, hum... If I had a hammer...

from pyparsing import *

word = Word(alphas)
sep = Literal('_').suppress()
pair = Group(word + sep + word)
pairs = delimitedList(pair, '_')

print ','.join(':'.join(t) for t in
pairs.parseString('hi_cat_bye_dog').asList())

--
Neil Cerutti <mr.cerutti+python@gmail.com>

Neil Cerutti

1/9/2008 1:43:00 PM

0

On Jan 9, 2008 5:34 AM, cesco <fd.calabrese@gmail.com> wrote:
> Hi,
>
> say I have a string like the following:
> s1 = 'hi_cat_bye_dog'
> and I want to replace the even '_' with ':' and the odd '_' with ','
> so that I get a new string like the following:
> s2 = 'hi:cat,bye:dog'
> Is there a common recipe to accomplish that? I can't come up with any
> solution...
>
> Thanks in advance

Hum, hum... If I had a hammer...
from pyparsing import *

word = Word(alphas)
sep = Literal('_').suppress()
pair = Group(word + sep + word)
pairs = delimitedList(pair, '_')

print ','.join(':'.join(t) for t in
pairs.parseString('hi_cat_bye_dog').asList())

--
Neil Cerutti <mr.cerutti+python@gmail.com>

Pablo Ziliani

1/9/2008 2:09:00 PM

0

cesco wrote:
> Hi,
>
> say I have a string like the following:
> s1 = 'hi_cat_bye_dog'
> and I want to replace the even '_' with ':' and the odd '_' with ','
> so that I get a new string like the following:
> s2 = 'hi:cat,bye:dog'
> Is there a common recipe to accomplish that? I can't come up with any
> solution...

What about:

>>> import re
>>> s1 = 'hi_cat_bye_dog'
>>> print re.sub(r'([^_]+)_([^_]+)_?', r'\1:\2;', s1)
hi:cat;bye:dog;

it still works for a longer string:
>>> s1 = 'hi_cat_bye_dog_' + s1
>>> s1
'hi_cat_bye_dog_hi_cat_bye_dog'
>>> print re.sub(r'([^_]+)_([^_]+)_?', r'\1:\2;', s1)
hi:cat;bye:dog;hi:cat;bye:dog;


Donald 'Paddy' McCarthy

1/9/2008 8:29:00 PM

0

cesco wrote:
I created some more test strings and ran posters solutions against them.

results attached.

- Paddy.





# alternating_replacements.py

tests = " 1 2_ 3_4 5_6_ 7_8_9 10_11_12_ 13_14_15_16 17_18_19_20_" " _ _21 _22_ _23_24 _25_26_ _27_28_29 _30_31_32_ _33_34_35_36" " __ ___ ____ _____".split(" ")

def altrep0(s):
s1 = s.split("_")
s1 = [s1[i]+":"+s1[i+1] for i in range(0,len(s1),2)]
s1 = ",".join(s1)
return s1
altrep0.author="Frederik Lundh"

def altrep1(s):
from re import sub
def repl(o):
repl.n = not repl.n
return ":" if repl.n else ","
repl.n = False
return sub("_", repl, s)
altrep1.author="bearophile"

def altrep2(s):
evenOrOdd = True
s2 = ""
for i in s:
if i == '_':
if evenOrOdd:
s2 += ':'
evenOrOdd = not evenOrOdd
else:
s2 += ','
evenOrOdd = not evenOrOdd
else:
s2 += i
return s2
altrep2.author="cokofree"

def altrep3(s):
import re
from itertools import cycle
return re.sub("_", lambda m, c=cycle(":,").next: c(), s)
altrep3.author="Peter Otten"

def altrep4(s):
from itertools import islice, cycle
def interleave(*iterators):
iterators = [ iter(i) for i in iterators ]
while 1:
for i in iterators:
yield i.next()
def punctuate(s):
parts = s.split('_')
punctuation = islice(cycle(':,'), len(parts)-1)
return ''.join(interleave(parts, punctuation))

return punctuate(s)
altrep4.author="Duncan Booth"

def altrep5(s):
import re
return re.sub(r'([^_]+)_([^_]+)_?', r'\1:\2;', s)
altrep5.author="Pablo Ziliani"

progs = [ altrep0, altrep1, altrep2, altrep3, altrep4, altrep5]

def testall():
'''
>>> testall()

## Program by: Frederik Lundh
'' RETURNS '<type 'exceptions.IndexError'>'
'1' RETURNS '<type 'exceptions.IndexError'>'
'2_' RETURNS '2:'
'3_4' RETURNS '3:4'
'5_6_' RETURNS '<type 'exceptions.IndexError'>'
'7_8_9' RETURNS '<type 'exceptions.IndexError'>'
'10_11_12_' RETURNS '10:11,12:'
'13_14_15_16' RETURNS '13:14,15:16'
'17_18_19_20_' RETURNS '<type 'exceptions.IndexError'>'
'_' RETURNS ':'
'_21' RETURNS ':21'
'_22_' RETURNS '<type 'exceptions.IndexError'>'
'_23_24' RETURNS '<type 'exceptions.IndexError'>'
'_25_26_' RETURNS ':25,26:'
'_27_28_29' RETURNS ':27,28:29'
'_30_31_32_' RETURNS '<type 'exceptions.IndexError'>'
'_33_34_35_36' RETURNS '<type 'exceptions.IndexError'>'
'__' RETURNS '<type 'exceptions.IndexError'>'
'___' RETURNS ':,:'
'____' RETURNS '<type 'exceptions.IndexError'>'
'_____' RETURNS ':,:,:'

## Program by: bearophile
'' RETURNS ''
'1' RETURNS '1'
'2_' RETURNS '2:'
'3_4' RETURNS '3:4'
'5_6_' RETURNS '5:6,'
'7_8_9' RETURNS '7:8,9'
'10_11_12_' RETURNS '10:11,12:'
'13_14_15_16' RETURNS '13:14,15:16'
'17_18_19_20_' RETURNS '17:18,19:20,'
'_' RETURNS ':'
'_21' RETURNS ':21'
'_22_' RETURNS ':22,'
'_23_24' RETURNS ':23,24'
'_25_26_' RETURNS ':25,26:'
'_27_28_29' RETURNS ':27,28:29'
'_30_31_32_' RETURNS ':30,31:32,'
'_33_34_35_36' RETURNS ':33,34:35,36'
'__' RETURNS ':,'
'___' RETURNS ':,:'
'____' RETURNS ':,:,'
'_____' RETURNS ':,:,:'

## Program by: cokofree
'' RETURNS ''
'1' RETURNS '1'
'2_' RETURNS '2:'
'3_4' RETURNS '3:4'
'5_6_' RETURNS '5:6,'
'7_8_9' RETURNS '7:8,9'
'10_11_12_' RETURNS '10:11,12:'
'13_14_15_16' RETURNS '13:14,15:16'
'17_18_19_20_' RETURNS '17:18,19:20,'
'_' RETURNS ':'
'_21' RETURNS ':21'
'_22_' RETURNS ':22,'
'_23_24' RETURNS ':23,24'
'_25_26_' RETURNS ':25,26:'
'_27_28_29' RETURNS ':27,28:29'
'_30_31_32_' RETURNS ':30,31:32,'
'_33_34_35_36' RETURNS ':33,34:35,36'
'__' RETURNS ':,'
'___' RETURNS ':,:'
'____' RETURNS ':,:,'
'_____' RETURNS ':,:,:'

## Program by: Peter Otten
'' RETURNS ''
'1' RETURNS '1'
'2_' RETURNS '2:'
'3_4' RETURNS '3:4'
'5_6_' RETURNS '5:6,'
'7_8_9' RETURNS '7:8,9'
'10_11_12_' RETURNS '10:11,12:'
'13_14_15_16' RETURNS '13:14,15:16'
'17_18_19_20_' RETURNS '17:18,19:20,'
'_' RETURNS ':'
'_21' RETURNS ':21'
'_22_' RETURNS ':22,'
'_23_24' RETURNS ':23,24'
'_25_26_' RETURNS ':25,26:'
'_27_28_29' RETURNS ':27,28:29'
'_30_31_32_' RETURNS ':30,31:32,'
'_33_34_35_36' RETURNS ':33,34:35,36'
'__' RETURNS ':,'
'___' RETURNS ':,:'
'____' RETURNS ':,:,'
'_____' RETURNS ':,:,:'

## Program by: Duncan Booth
'' RETURNS ''
'1' RETURNS '1'
'2_' RETURNS '2:'
'3_4' RETURNS '3:4'
'5_6_' RETURNS '5:6,'
'7_8_9' RETURNS '7:8,9'
'10_11_12_' RETURNS '10:11,12:'
'13_14_15_16' RETURNS '13:14,15:16'
'17_18_19_20_' RETURNS '17:18,19:20,'
'_' RETURNS ':'
'_21' RETURNS ':21'
'_22_' RETURNS ':22,'
'_23_24' RETURNS ':23,24'
'_25_26_' RETURNS ':25,26:'
'_27_28_29' RETURNS ':27,28:29'
'_30_31_32_' RETURNS ':30,31:32,'
'_33_34_35_36' RETURNS ':33,34:35,36'
'__' RETURNS ':,'
'___' RETURNS ':,:'
'____' RETURNS ':,:,'
'_____' RETURNS ':,:,:'

## Program by: Pablo Ziliani
'' RETURNS ''
'1' RETURNS '1'
'2_' RETURNS '2_'
'3_4' RETURNS '3:4;'
'5_6_' RETURNS '5:6;'
'7_8_9' RETURNS '7:8;9'
'10_11_12_' RETURNS '10:11;12_'
'13_14_15_16' RETURNS '13:14;15:16;'
'17_18_19_20_' RETURNS '17:18;19:20;'
'_' RETURNS '_'
'_21' RETURNS '_21'
'_22_' RETURNS '_22_'
'_23_24' RETURNS '_23:24;'
'_25_26_' RETURNS '_25:26;'
'_27_28_29' RETURNS '_27:28;29'
'_30_31_32_' RETURNS '_30:31;32_'
'_33_34_35_36' RETURNS '_33:34;35:36;'
'__' RETURNS '__'
'___' RETURNS '___'
'____' RETURNS '____'
'_____' RETURNS '_____'
>>>
'''
import sys
for prog in progs:
print "\n## Program by:", prog.author
for test in tests:
try:
answer = prog(test)
except:
answer = sys.exc_info()[0]
print "%14s RETURNS '%s'" % ("'%s'" % (test,), answer)

if __name__ == "__main__":
testall()