switch recipe?
Mark McEahern
marklists at mceahern.com
Mon Jul 15 15:31:23 EDT 2002
I want to thank everyone who posted to this thread. I've gotten many
excellent suggestions. The following demo presents all the distinct
variations I culled from the thread. I like Emile's suggestion of the name
cycler, but I didn't use it in this demo--I think partly because for better
or worse alternator has lodged itself in my brain.
Cheers,
// mark
#! /usr/bin/env python
from __future__ import generators
import unittest
def weave(setn, setm):
"""Return a generator that iterates over setn and setm until setn is
exhausted. If setn is larger than setm, cycle over setm.
"""
m = len(setm)
if not setn or not setm:
raise ValueError, "Weaved sets cannot be empty"
for i in range(len(setn)):
yield setn[i], setm[i%m]
def finite_alternator(length, *args):
"""Return a finite repeating alternator for args."""
c = 0
while args and c < length:
for a in args:
yield a
c += 1
if c >= length:
break
def take(n, it):
"""Return n elements from the unbounded iterator."""
for j in xrange(n):
yield it.next()
def repeating_alternator(*args):
"""Return a repeating alternator for args."""
while args:
for a in args:
yield a
def weave_items(iterator, alternator, weave_item):
"""Iterate over iterator, applying weave_item to each item with its
pair in alternator.
"""
for item in iterator:
yield weave_item(item, alternator.next())
def color_item(item, color):
template = "<%(color)s>%(item)s</%(color)s>"
return template % locals()
class test(unittest.TestCase):
def setUp(self):
self.colors = ("red", "orange", "yellow", "green", "blue", "indigo",
"violet")
self.expected = ['<red>0</red>',
'<orange>1</orange>',
'<yellow>2</yellow>',
'<green>3</green>',
'<blue>4</blue>',
'<indigo>5</indigo>',
'<violet>6</violet>',
'<red>7</red>',
'<orange>8</orange>',
'<yellow>9</yellow>']
self.length = 10
def test_weave(self):
colors = self.colors
length = self.length
expected = self.expected
generated = [color_item(x, y) for x, y in weave(range(length),
colors)]
self.assertEquals(expected, generated)
def test_zip(self):
colors = self.colors
length = self.length
expected = self.expected
iterator = range(length)
alternator = repeating_alternator(*colors)
weaved = zip(iterator, alternator)
generated = [color_item(x, y) for x, y in weaved]
self.assertEquals(expected, generated)
def test_list_comprehension(self):
colors = self.colors
length = self.length
expected = self.expected
iterator = range(length)
alternator = repeating_alternator(*colors)
generated = [color_item(x, alternator.next()) for x in iterator]
self.assertEquals(expected, generated)
def test_map(self):
colors = self.colors
length = self.length
expected = self.expected
iterator = range(length)
alternator = finite_alternator(length, *colors)
generated = map(color_item, iterator, alternator)
self.assertEquals(expected, generated)
def test_map2(self):
colors = self.colors
length = self.length
expected = self.expected
iterator = range(length)
alternator = repeating_alternator(*colors)
generated = map(color_item, iterator, take(length, alternator))
self.assertEquals(expected, generated)
def test_weave_items(self):
colors = self.colors
length = self.length
expected = self.expected
iterator = range(length)
alternator = repeating_alternator(*colors)
generated = [x for x in weave_items(iterator, alternator,
color_item)]
self.assertEquals(expected, generated)
def test_empty(self):
r = repeating_alternator()
self.assertRaises(StopIteration, r.next)
if __name__ == "__main__":
unittest.main()
-
More information about the Python-list
mailing list