can't generate list from iterator [was: can't generate iterator from list]

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Sep 10 02:55:53 CEST 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