[Tutor] when is a generator "smart?"

Dave Angel davea at davea.name
Sun Jun 2 12:39:05 CEST 2013


On 06/01/2013 11:58 PM, Jim Mooney wrote:
> It's a little unclear to me where generators are more efficient.

I'm astounded nobody has asked you what version of Python this is for. 
in Python 2.x, the range(x,y) function produces the whole list, and then 
the expression around it converts that to a generator.  That alone would 
make it waste tons of memory (and time) for large y.

So I'll ASSUME you're using 3.x, or that you actually are using xrange 
below.

> Below
> I'm creating a list of non-even squares. I figured Python would be
> smart enough to see I only wanted a small slice of a large generated
> list, but as I increased y, Py got slower and eventually died of a
> memory  error. If I don't make it into a list I get a type error. So
> where are generators more efficient? Or more specifically, how would i
> make this efficient and use the generator to only pick out the small
> 2:10 slice I really want, but leave the capability of the entire list
> if I wanted to slice and dice it in different ways further on?
>
> def uneven_squares(x,y):
>      squarelist = (c**2 for c in range(x,y) if c%2 != 0)
>      return squarelist #returning a generator
>
> print(list(uneven_squares(10,10000))[2:10]) #slows as y gets bigger, then dies
>

So the real question is how to slice a generator without first 
converting it to a list.

That's what iterator.islice() is for.

Try (untested):
import iterator

def uneven_squares(x,y):
  ....

print( iterator.islice(uneven_squares(10, 10000), 2, 10) )


-- 
DaveA


More information about the Tutor mailing list