i have a generator where i would like to add an initial and final value to the actual content, it\'s something like this:
# any generic queue where i would like
Here's a code in which use of StopIteration isn't required, a break is enough:
li = [12,51,98,4,36,99,33,1,125,78,9,369,48,47,214,4]
def gen( cont, header='something', footer='anything' ):
yield header
for x in cont:
if x<100:
yield x
else:
yield footer
break
for y in gen(li):
print '1 or 2 digits only:',y
result
1 or 2 digits only: something
1 or 2 digits only: 12
1 or 2 digits only: 51
1 or 2 digits only: 98
1 or 2 digits only: 4
1 or 2 digits only: 36
1 or 2 digits only: 99
1 or 2 digits only: 33
1 or 2 digits only: 1
1 or 2 digits only: anything
Now, here's a moderately complex code in which it seems to me that we can't do without use of StopIteration. Does this interest you ?
import Queue
q = Queue.Queue()
li = [12,51,98,4,36,99,33,1,125,78,9,369,48,47,214,4]
def gen( cont, header='something', footer='anything' ):
def qput(ili = [0]):
eli = li[ili[0]]
q.put(eli)
ili[0] = ili[0] + 1
return eli
qput()
qput()
qput()
qput()
qput()
yield header
while True:
try:
print '\nq.qsize() first is %s' % q.qsize()
el = q.get(None)
if el>9:
print 'el==',el
yield 1000+el
qput()
else:
print 'el==%s el//3==%s' % (el,el//3)
print 'there are %s items in q and q is emptied %s times :' % (q.qsize(),el//3)
for emp in xrange(el//3):
print '%s is removed from q' % q.get(None)
if q.qsize()==0 and emp<el//3:
print 'ah !! q is now completely empty, no more emptying is possible !'
print 'q.qsize() second is %s' % q.qsize()
except Queue.Empty:
yield footer
raise StopIteration
print 'li == %s\n' % li
for i,nb in enumerate(gen(li)):
print ' * obtained from enumerate(gen(li)) : %s - %s' % (i,nb)
result
li == [12, 51, 98, 4, 36, 99, 33, 1, 125, 78, 9, 369, 48, 47, 214, 4]
* obtained from enumerate(gen(li)) : 0 - something
q.qsize() first is 5
el== 12
* obtained from enumerate(gen(li)) : 1 - 1012
q.qsize() second is 5
q.qsize() first is 5
el== 51
* obtained from enumerate(gen(li)) : 2 - 1051
q.qsize() second is 5
q.qsize() first is 5
el== 98
* obtained from enumerate(gen(li)) : 3 - 1098
q.qsize() second is 5
q.qsize() first is 5
el==4 el//3==1
there are 4 items in q and q is emptied 1 times :
36 is removed from q
q.qsize() second is 3
q.qsize() first is 3
el== 99
* obtained from enumerate(gen(li)) : 4 - 1099
q.qsize() second is 3
q.qsize() first is 3
el== 33
* obtained from enumerate(gen(li)) : 5 - 1033
q.qsize() second is 3
q.qsize() first is 3
el==1 el//3==0
there are 2 items in q and q is emptied 0 times :
q.qsize() second is 2
q.qsize() first is 2
el== 125
* obtained from enumerate(gen(li)) : 6 - 1125
q.qsize() second is 2
q.qsize() first is 2
el== 78
* obtained from enumerate(gen(li)) : 7 - 1078
q.qsize() second is 2
q.qsize() first is 2
el==9 el//3==3
there are 1 items in q and q is emptied 3 times :
369 is removed from q
ah !! q is now completely empty, no more emptying is possible !
* obtained from enumerate(gen(li)) : 8 - anything
Note that this program runs correctly only with q.get(None)
, not q.get()
You seem to be overcomplicating this quite a bit:
>>> q = [1, 2, 3, 4]
>>> def gen(header='something', footer='anything'):
yield header
for thing in q:
yield thing
yield footer
>>> for tmp in gen():
print(tmp)
something
1
2
3
4
anything
StopIteration
will automatically be raised when a generator stops yielding. It's part of the protocol of how generators work. Unless you're doing something very complex, you don't need to (and shouldn't) deal with StopIteration
at all. Just yield
each value you want to return from the generator in turn, then let the function return.