funny generator behaviour

pruebauno at latinmail.com pruebauno at latinmail.com
Thu Dec 4 09:50:31 EST 2008


On Dec 4, 8:00 am, Edvin Fuglebakk <Edvin.Fugleb... at ii.uib.no> wrote:
> I have written a generator that puzzles me:
>
> The generator is supposed to create ordered selections of a set of
> objects. repetition of objects is allowed and the selections should be
> of a size determined by a pramter to the generator.
>
> Now, if I try to accummulate the generated selections into a list I get
> some peculiar behaviour that I hope maybe some of you can help me
> understand:
>
> Help much appreciated
> -Edvin
>
> #straightforward acumulation. Does not give the expected result
>  >>> d=[]
>  >>> for f in orderedCombinations([1,2],3):
> ...     d.append(f)
> ...
>  >>> d
> [[1], [2], [1], [2], [1], [2], [1], [2]]
>
> #accumulating shallow copies of the genereated combinations works:
>  >>> d=[]
>  >>> for f in orderedCombinations([1,2],3):
> ...     d.append(f[:])
> ...
>  >>> d
> [[1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 2, 2], [2, 1, 1], [2, 1, 2], [2,
> 2, 1], [2, 2, 2]]
>
> #The generator:
> def orderedCombinations(pool, k):
>     """
>     Generator yielding ordered selections of size k with repetition from
> pool.
>     """
>
>     if k == 1:
>         for m in pool:
>             yield [m]
>
>     if k > 1:
>
>         for m in pool:
>             for combo in orderedCombinations(pool, k-1):
>
>                 #insert and pop to avoid copying entire list
>                 combo.insert(0,m)
>                 yield combo
>                 combo.pop(0)

Functional style (like the recursion you are using) and mutable
datastructures are hard to reason about. This version works for me:

def orderedCombinations(pool, k):
    """
    Generator yielding ordered selections of size k with repetition
from
pool.
    """

    if k == 1:
        for m in pool:
            yield [m]

    if k > 1:

        for m in pool:
            for combo in orderedCombinations(pool, k-1):
                yield [m]+combo



More information about the Python-list mailing list