switch recipe?
Mark McEahern
marklists at mceahern.com
Sat Jul 13 10:08:55 EDT 2002
[Christian Tanzer]
> Not so. As long as one of the iterators is finite, zip will work:
>
> >>> from __future__ import generators
> >>> def repeat(*args):
> ... """Return a repeating alternator for args."""
> ... while args:
> ... for a in args:
> ... yield a
> ...
> >>> for i, j in zip(range(5), repeat("a","b","c")):
> ... print i, j
> ...
> 0 a
> 1 b
> 2 c
> 3 a
> 4 b
I just saw Office Space for the first time last night. One of the
characters in the movie develops a prototype for a Jumping To Conclusions
mat. That's certainly what I did about zip, assuming that it had similar
behavior to map when it came to unbounded iterators. As you point out,
that's not true.
Because I want to do something to the zipped items, it doesn't seem like zip
solves all my problems, though. map would, if it had the same behavior as
zip--namely that it stopped once one of the iterators ran out of items.
Below is a version that shows the use of zip. Here are the key lines:
weaved = zip(iterator, alternator)
generated = [color_item(x, y) for x, y in weaved]
Perhaps what I'm still looking for is a way to
weave-two-iterators-with-a-function all at once. One solution would be to
modify or wrap repeating_alternator() so that it was finite--then I could
just use map.
Thanks!
// mark
#! /usr/bin/env python
from __future__ import generators
import unittest
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 test(self):
iterator = range(10)
colors = ("red", "organge", "yellow", "green", "blue", "indigo",
"violet")
alternator = repeating_alternator(*colors)
expected = ['<red>0</red>',
'<organge>1</organge>',
'<yellow>2</yellow>',
'<green>3</green>',
'<blue>4</blue>',
'<indigo>5</indigo>',
'<violet>6</violet>',
'<red>7</red>',
'<organge>8</organge>',
'<yellow>9</yellow>']
weaved = zip(iterator, alternator)
generated = [color_item(x, y) for x, y in weaved]
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