# funny generator behaviour

Thu Dec 4 17:57:57 CET 2008

```Edvin Fuglebakk <Edvin.Fuglebakk at ii.uib.no> writes:

> 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

I haven't tried your code but I think the problem is that you yield a
list above and then mutate it below, so when you generate the next
combination the previous one is mutated.  Change the above line to

yield list(combo)

and it should sort the problem.

>                combo.pop(0)

--
Arnaud

```