Why can yield be indexed?
<p>I thought I could make my python (2.7.10) code simpler by directly accessing the index of a value passed to a generator via <code>send</code>, and was surprised the code ran. I then discovered an index applied to <code>yield</code> doesn't really do anything, nor does it throw an exception:</p>

<pre><code>def gen1():
    t = yield[0]
    assert t
    yield False

g = gen1()
next(g)
g.send('char_str')
</code></pre>

<p>However, if I try to index <code>yield</code> thrice or more, I get an exception:</p>

<pre><code>def gen1():
    t = yield[0][0][0]
    assert t
    yield False

g = gen1()
next(g)
g.send('char_str')
</code></pre>

<p>which throws</p>

<pre><code>TypeError: 'int' object has no attribute '__getitem__'
</code></pre>

<p>This was unusually inconsistent behavior, and I was wondering if there is an intuitive explanation for what indexing yield is actually doing?</p>

<p>You are not indexing. You are yielding a list; the expression <code>yield[0]</code> is really just the same as the following (but without a variable):</p>

<pre><code>lst = [0]
yield lst
</code></pre>

<p>If you look at what <code>next()</code> returned you'd have gotten that list:</p>

<pre><code>&gt;&gt;&gt; def gen1():
...   t = yield[0]
...   assert t
...   yield False
...
&gt;&gt;&gt; g = gen1()
&gt;&gt;&gt; next(g)
[0]
</code></pre>

<p>You don't <em>have</em> to have a space between <code>yield</code> and the <code>[0]</code>, that's all.</p>

<p>The exception is caused by you trying to apply the subscription to the contained <code>0</code> integer:</p>

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

<p>If you want to index a value sent to the generator, put parentheses around the <code>yield</code> expression:</p>

<pre><code>t = (yield)[0]
</code></pre>

<p>Demo:</p>

<pre><code>&gt;&gt;&gt; def gen1():
...     t = (yield)[0]
...     print 'Received: {!r}'.format(t)
...     yield False
...
&gt;&gt;&gt; g = gen1()
&gt;&gt;&gt; next(g)
&gt;&gt;&gt; g.send('foo')
Received: 'f'
False
</code></pre>

python python-2.7 indexing generator yield