Python Forum
Use generator with sring replacement... [solved]
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Use generator with sring replacement... [solved]
#1
Thumbs Up 
Hi

I would like to have a simple generator like

def alternate():

    while True:
        yield 'yes'
        yield 'no'

#generator
YN = alternate()

sample = '!A!A'.replace('!A',next(YN))
So I'm expecting yesno instead I got
Output:
yesyes
I've tried also with re.sub(), but still the same outcome..

any ideas ?

Thanks.
[Image: NfRQr9R.jpg]
Reply
#2
Nevermind ;)

I've found a solution. I'll post tomorrow. cheers
[Image: NfRQr9R.jpg]
Reply
#3
Hi,

the replace methods for strings expects min two arguments: the string to replace and what it should be replaced with - as you correctly use. Your alternativefunction / generator returns exactly one string, alternating between yes and no. So next(YN) return either yes or no. Your program does exactly what you programmed - your expectation is wrong. You are expecting the generator to return twice a value with one call only - this won't work.

What are you really trying to achieve? I guess the hyper simplified example isn't the real world code you are running. In the given example, using a generator is pointless and the replacement doesn't really make sense. I guess it would help (you) a lot to deliver a bit more context.

Regards, noisefloor
Reply
#4
Don't like the look of that while True without any exit condition! Better use range.

def alternate(): 
    for i in range(5):
            yield 'yes'
            yield 'no'

#generator
YN = alternate()
for duh in YN:
    print('!A!A'.replace('!A', duh)) 
Sorry, as usual I didn't read the question carefully. You want "yesno" as output, I believe.

def yes(): 
    for i in range(5):
            yield 'yes'

def no(): 
    for j in range(5):
           yield 'no'
#generator
ja = yes()
nein = no()

for k in range(5):
    word = next(ja) + next(nein)
    print('!A!A'.replace('!A!A', word))
But that seems unnecessarily complicated.

out = ('yesno' for i in range(5))
for o in out:
    print( '!A!A'.replace('!A', o))
The above gives a double 'yesnoyesno' change replace('!A' for replace('!A!A' if you want just 'yesno'
Reply
#5
Or, to stick with your original idea:

def alternate(): 
    for i in range(5):
            yield 'yes'
            yield 'no'
 
#generator
YN = alternate()
for duh in YN:
    word = duh + next(YN)
    print('!A!A'.replace('!A!A', word)) 
Reply
#6
The function argument is evaluated first. The result is passed to the function. Your code is identical in functionality to:
word = next(YN)
sample = '!A!A'.replace('!A', word)
There is no way you can make replace() call next(YN) twice. You can pass a function (or generator) as an argument, and call the function multiple times, or have the function return multiple values, but that only works because everybody is in on the trick.
Reply
#7
Although this smells like XY problem from miles away
in python 3.12+

from itertools import cycle, batched

replacement = batched(cycle(['yes', 'no']), 2)
print('A!A!'.replace('A!A!', ''.join(next(replacement))))
Output:
yesno

And another go

from itertools import cycle

replacement = cycle(['yes', 'no'])
foo, bar = 'A!A!A!', None
while foo != bar:
    bar, foo = foo, foo.replace('A!', next(replacement), 1)
print(foo)
noisefloor likes this post
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#8
I don't think this is an XY problem. I think it is a "How does X work" question. The answer is that passing a generator result as an argument passes the result, not the generator. calling next(YN) passed "yes" to replace(), not the generator YN.

cycle and batch do not solve the "problem", they are tools that let you write a solution around the problem. It's no different than writing this:
from itertools import cycle, batched


def alternate():
    while True:
        yield "yes"
        yield "no"


def generator_replace(string, pattern, generator):
    result = string
    while pattern in result:
        result = result.replace(pattern, next(generator), 1)
    return result


print(generator_replace("A A", "A", alternate()))
print(generator_replace("B B B", "B", cycle(("yes", "no"))))
print(generator_replace("C C C C", "C", cycle(("yes", "no"))))
Somewhere, somebody has to do a loop, and you have to write the loop.
Reply
#9
I forgot replace has a count parameter!

def alternate(): 
    yield 'yes'
    yield 'no'
        
#generator
YN = alternate()
 
sample = '!A!A'.replace('!A',next(YN), 1)
newsample = sample.replace('!A',next(YN), 1) # don't need count here
replace does not overwrite the original string, i.e. sample
Reply
#10
Amazing what one thinks of whilst cycling!

def alternate(): 
    for i in range(5):
            yield 'yes'
            yield 'no'

YN = alternate()            
for duh in YN:
    print('!A!A'.replace('!A', duh, 1).replace('!A',next(YN)))
I'll stop now!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  If I need to do regex replacement 27000 times, how to shorten it? tatahuft 4 1,546 Dec-26-2024, 01:51 AM
Last Post: deanhystad
  replacement for fpformat.extract GbSig1998 4 2,021 Apr-12-2024, 06:15 PM
Last Post: deanhystad
  String replacement in DB WJSwan 0 1,636 Dec-28-2022, 05:31 AM
Last Post: WJSwan
Exclamation IndexError: Replacement index 2 out of range for positional args tuple - help? MrKnd94 2 16,795 Oct-14-2022, 09:57 PM
Last Post: MrKnd94
  Extract the largest value from a group without replacement (beginner) preliator 1 3,125 Aug-12-2020, 01:56 PM
Last Post: DPaul
  Simple automated SoapAPI Call with single variable replacement from csv asaxty 1 3,373 Jun-30-2020, 06:38 PM
Last Post: asaxty
  line replacement help mdalireza 8 5,931 Nov-11-2019, 12:54 PM
Last Post: mdalireza
  xml replacement with python josesalazmit 3 10,569 Feb-24-2019, 07:28 PM
Last Post: stullis
  Best replacement for pyzmail in lines 15 and 16 Pedroski55 0 3,583 Nov-03-2018, 06:12 AM
Last Post: Pedroski55
  receive from a generator, send to a generator Skaperen 9 8,742 Feb-05-2018, 06:26 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020