James Stroud schrieb:
Ken Pu wrote:
Hi, below is the code I thought should create two generates, it[0] =
0,1,2,3,4,5, and it[1] = 0,10,20,30,..., but they turn out to be the
same!!!
from itertools import *
itlist = [0,0]
for i in range(2):
itlist[i] = (x+(i*10) for x in count())
print "what's in the bags:"
print list(islice(itlist[0], 5))
print list(islice(itlist[1], 5))
The output is:
[10, 11, 12, 13, 14]
[10, 11, 12, 13, 14]
I see what Python is doing -- lazy evaluation doesn't evaluate
(x+(i*10) for x in count()) until the end.
It doesn't evaluate it until you ask it to, which is the right
behavior. However, when evaluated, it evaluates "i" also, which is the
last value to which "i" was assigned, namely the integer 1. I'm going
to get flamed pretty hard for this, but it doesn't seem to be the
intuitive behavior to me either. However, in a purely functional
language, you wouldn't be able to construct a list of generators in
this way.
With python, you have to remember to adopt a purely functional design
and then pray for best results. You can store generators in a list,
but they need to be constructed properly. I can't perfectly
transmogrify your code into functional code because I don't think
making the particular anonymous generator you want is possible in
python. However this is how I would make a close approximation:
from itertools import *
def make_gen(i):
for x in count():
yield x + (i * 10)
itlist = [make_gen(i) for i in xrange(2)]
print "what's in the bags:"
print list(islice(itlist[0], 5))
print list(islice(itlist[1], 5))
James
You could just as well use the original expression in make_gen, too:
from itertools import *
def make_gen(i):
return (x + (i*10) for x in count())
itlist = [make_gen(i) for i in xrange(2)]
print "what's in the bags:"
print list(islice(itlist[0], 5))
print list(islice(itlist[1], 5))
what's in the bags:
[0, 1, 2, 3, 4]
[10, 11, 12, 13, 14]
--
http://mail.python.org/mailman/listinfo/python-list