Why is it possible to index?

I thought I could make my python code (2.7.10) easier by directly accessing the index of the value passed to the generator via send , and was surprised that the code was running. Then I found that the index applied to yield does nothing and does not throw an exception:

 def gen1(): t = yield[0] assert t yield False g = gen1() next(g) g.send('char_str') 

However, if I try to index yield three times or more, I get an exception:

 def gen1(): t = yield[0][0][0] assert t yield False g = gen1() next(g) g.send('char_str') 

which throws

 TypeError: 'int' object has no attribute '__getitem__' 

This was an unusually inconsistent behavior, and I was wondering if there is an intuitive explanation for what indexing profitability does.

+6
source share
1 answer

You are not indexing. You get a list; expression yield[0] really the same as the following (but without a variable):

 lst = [0] yield lst 

If you look what next() returns, you would get this list:

 >>> def gen1(): ... t = yield[0] ... assert t ... yield False ... >>> g = gen1() >>> next(g) [0] 

You do not need to have a space between yield and [0] , that's all.

The exception is caused by the fact that you are trying to apply a subscription to the contained 0 integer:

 >>> [0] # list with one element, the int value 0 [0] >>> [0][0] # indexing the first element, so 0 0 >>> [0][0][0] # trying to index the 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not subscriptable 

If you want to index the value sent to the generator, put the brackets around the yield expression:

 t = (yield)[0] 

Demo:

 >>> def gen1(): ... t = (yield)[0] ... print 'Received: {!r}'.format(t) ... yield False ... >>> g = gen1() >>> next(g) >>> g.send('foo') Received: 'f' False 
+13
source

All Articles