switch recipe?

Alex Martelli aleax at aleax.it
Tue Jul 16 05:29:37 EDT 2002


Mark McEahern wrote:

> [Alex Martelli]
>> Right.  So what about a direct implementation of what you just said?
>>
>> def weave(setn, setm):
>>     n = len(setn)
>>     m = len(setm)
>>     if not n or not m:
>>         raise ValueError, "Weaved sets cannot be empty"
>>     yield setn[0], setm[0]
>>     i = 1
>>     while i%n or i%m:
>>         yield setn[i%n], setm[i%m]
>>         i += 1
> 
> I like this.  The 'or' in the while statment means this will loop until
> lcd(n, m)--easily fixed.  I modified this slightly:

I'm not sure what an lcd is in this context, but I did mean to
loop least-common-multiple(m, n) times, treating the two sets
as equivalent.  So I guess I had misunderstood the specs!


> 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]
> 
> This means you have to specify the alternator/cycler second--it doesn't
> treat the two sets as interchangeable.  Slightly less general than the
> direction your solution points.

Yep.  Nicer in Python 2.3 of course:

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."""
    if not setn or not setm:
        raise ValueError, "Weaved sets cannot be empty"
    m = len(setm)
    for index, item in enumerate(setn):
        yield item, setm[index%m]

Here, actually, an empty setn SHOULD be quite acceptable -- as no
cycling is done on it, that should be OK, and only an empty setm
should be a problem. So, I'd prefer:

def weave(setn, setm):
    """Return an iterator that iterates over iterator setn and 
    sequence setm until setn is exhausted.  If setn is larger than 
    setm, cycle over setm."""
    m = len(setm)
    if not m:
        raise ValueError, "Set to be cycled on cannot be empty"
    for index, item in enumerate(setn):
        yield item, setm[index%m]


Alex




More information about the Python-list mailing list