Best way to generate alternate toggling values in a loop?

D

Debajit Adhikary

I'm writing this little Python program which will pull values from a
database and generate some XHTML.

I'm generating a <table> where I would like the alternate <tr>'s to be

<tr class="Even">
and
<tr class="Odd">

What is the best way to do this?

I wrote a little generator (code snippet follows). Is there a better
(more "Pythonic") way to do this?


# Start of Code

def evenOdd():
values = ["Even", "Odd"]
state = 0
while True:
yield values[state]
state = (state + 1) % 2


# Snippet

trClass = evenOdd()
stringBuffer = cStringIO.StringIO()

for id, name in result:
stringBuffer.write('''
<tr class="%s">
<td>%d</td>
<td>%s</td>
</tr>
'''
%
(trClass.next(), id, name))


# End of Code
 
C

Carsten Haese

I'm writing this little Python program which will pull values from a
database and generate some XHTML.

I'm generating a <table> where I would like the alternate <tr>'s to be

<tr class="Even">
and
<tr class="Odd">

What is the best way to do this?

I wrote a little generator (code snippet follows). Is there a better
(more "Pythonic") way to do this?


# Start of Code

def evenOdd():
values = ["Even", "Odd"]
state = 0
while True:
yield values[state]
state = (state + 1) % 2


# Snippet

trClass = evenOdd()
stringBuffer = cStringIO.StringIO()

for id, name in result:
stringBuffer.write('''
<tr class="%s">
<td>%d</td>
<td>%s</td>
</tr>
'''
%
(trClass.next(), id, name))

This is a respectable first attempt, but I recommend you familiarize
yourself with the itertools module. It has lots of useful tools for
making your code more elegant and concise.

Rather than spelling out the final result, I'll give you hints: Look at
itertools.cycle and itertools.izip.

HTH,
 
G

Grant Edwards

# Start of Code

def evenOdd():
values = ["Even", "Odd"]
state = 0
while True:
yield values[state]
state = (state + 1) % 2

I'd replace the last line with

state ^= 1

to save a couple instructions, but I spend too much time
working with micoroprocessors running on clocks measured in the
KHz.

There are probably other more Pythonic ways...
 
G

Gerard Flanagan

I'm writing this little Python program which will pull values from a
database and generate some XHTML.

I'm generating a <table> where I would like the alternate <tr>'s to be

<tr class="Even">
and
<tr class="Odd">

What is the best way to do this?


from itertools import izip

def toggle(start=True):
flag = start
while 1:
flag = not flag
yield flag


CSS = ("even", "odd")

HTML = '<tr class="%s"><td>%d</td><td>%s</td></tr>'

result = [(1, 'One'), (2, 'two'), (3, 'Three'), (4, 'Four'), (5,
'Five')]

for flag, (id, name) in izip(toggle(), result):
print HTML % (CSS[flag], id, name)


<tr class="even"><td>1</td><td>One</td></tr>
<tr class="odd"><td>2</td><td>two</td></tr>
<tr class="even"><td>3</td><td>Three</td></tr>
<tr class="odd"><td>4</td><td>Four</td></tr>
<tr class="even"><td>5</td><td>Five</td></tr>
 
A

Amit Khemka

I'm writing this little Python program which will pull values from a
database and generate some XHTML.

I'm generating a <table> where I would like the alternate <tr>'s to be

<tr class="Even">
and
<tr class="Odd">

What is the best way to do this?

I wrote a little generator (code snippet follows). Is there a better
(more "Pythonic") way to do this?


# Start of Code

def evenOdd():
values = ["Even", "Odd"]
state = 0
while True:
yield values[state]
state = (state + 1) % 2


# Snippet

trClass = evenOdd()
stringBuffer = cStringIO.StringIO()

for id, name in result:
stringBuffer.write('''
<tr class="%s">
<td>%d</td>
<td>%s</td>
</tr>
'''
%
(trClass.next(), id, name))

This is a respectable first attempt, but I recommend you familiarize
yourself with the itertools module. It has lots of useful tools for
making your code more elegant and concise.

Rather than spelling out the final result, I'll give you hints: Look at
itertools.cycle and itertools.izip.

Why not just use enumerate ?

clvalues = ["Even", "Odd"]
for i, (id, name) in enumerate(result):
stringBuffer.write('''
<tr class="%s">
<td>%d</td>
<td>%s</td>
</tr>
'''
%
(clvalues[i % 2], id, name))

Cheers,
 
P

Paul Hankin

Rather than spelling out the final result, I'll give you hints: Look at
itertools.cycle and itertools.izip.

Why not just use enumerate ?

clvalues = ["Even", "Odd"]
for i, (id, name) in enumerate(result):
stringBuffer.write('''
<tr class="%s">
<td>%d</td>
<td>%s</td>
</tr>
'''
%
(clvalues[i % 2], id, name))

I like this code: straightforward and pragmatic. Everyone else seems
to be reinventing itertools.cycle - they should have listened to
Carsten, and written something like this:

import itertools

clvalues = itertools.cycle(['Even', 'Odd'])
for clvalue, (id, name) in itertools.izip(clvalues, result):
stringBuffer.write('''
<tr class="%(name)s">
<td>%(id)d</td>
<td>%(clvalue)s</td>
</tr>''' % locals())
 
G

Grant Edwards

from itertools import izip

def toggle(start=True):
flag = start
while 1:
flag = not flag
yield flag

I like the solution somebody sent me via PM:

def toggle():
while 1:
yield "Even"
yield "Odd"
 
A

Alex Martelli

Grant Edwards said:
I like the solution somebody sent me via PM:

def toggle():
while 1:
yield "Even"
yield "Odd"

I think the itertools-based solution is more elegant:

toggle = itertools.cycle(('Even', 'Odd'))

and use toggle rather than toggle() later; or, just use that
itertools.cycle call inside the expression instead of toggle().


Alex
 
I

Iain King

# Start of Code
def evenOdd():
values = ["Even", "Odd"]
state = 0
while True:
yield values[state]
state = (state + 1) % 2

I'd replace the last line with

state ^= 1

to save a couple instructions, but I spend too much time
working with micoroprocessors running on clocks measured in the
KHz.

There are probably other more Pythonic ways...


I always use:

state = 1 - state

for toggles. I doubt it's much more pythonic though :)

Iain
 
C

cokofreedom

# Start of Code
def evenOdd():
values = ["Even", "Odd"]
state = 0
while True:
yield values[state]
state = (state + 1) % 2
I'd replace the last line with
state ^= 1
to save a couple instructions, but I spend too much time
working with micoroprocessors running on clocks measured in the
KHz.
There are probably other more Pythonic ways...

I always use:

state = 1 - state

for toggles. I doubt it's much more pythonic though :)

Iain

why not do
state = not state
?
 
L

Luis Zarrabeitia

I like the solution somebody sent me via PM:

def toggle():
while 1:
yield "Even"
yield "Odd"

That was me.
Sorry, list, I meant to send it to everyone but I my webmail didn't respect
the list* headers :(.

Thanks, Grant!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top