can't generate list from iterator [was: can't generate iterator from list]
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Fri Sep 9 20:55:53 EDT 2011
Dr. Phillip M. Feldman wrote:
>
> It is supposed to be possible to generate a list representation of any
> iterator that produces a sequence of finite length, but this doesn't
> always work. Here's a case where it does work:
>
> Input:
>
> from itertools import combinations
> list(combinations(range(4),2))
>
> Output:
>
> [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
>
> When I define my own classes that produce iterators, conversion to a list
> works for some of these classes but not for others. Here's a case where it
> doesn't work:
>
> In: list(balls_in_numbered_boxes(2, [3,3,3]))
>
> Out:
>
> [array([0, 0, 1]),
> array([0, 0, 1]),
> array([0, 0, 1]),
> array([0, 0, 1]),
> array([0, 0, 1])]
But it does work -- it generates a list, exactly as expected.
The problem is not that you can't generate a list. The problem is that the
list you generate is not what you expect.
What you have here is a list containing the same array, repeated three
times. When you print the permutations one at a time, you don't notice, but
by collecting them all at once, you see clearly that they are the same
array object. Try this:
combos = list(balls_in_numbered_boxes(2, [3,3,3]))
[id(a) for a in combos]
I expect you will see something like [123456, 123456, 123456].
The simplest fix is to fix the next() method so that it returns a copy of
self.distribution instead of the array itself.
--
Steven
More information about the Python-list
mailing list