title: ''.join(random.choice(chars) for _ in range(size))
body: <p>I have the following generator:</p>
  
  <pre><code>import random
  import string
  
  def random_string_generator(size = 10, chars = string.ascii_lowercase + string.digits):
  
      return "".join(random.choice(chars) for _ in range(size))
  </code></pre>
  
  <p>When I use interactive mode to inspect the generator, I get the following:</p>
  
  <pre><code>In [30]: random_string_generator()
  Out[30]: '6v0vhljxac'
  </code></pre>
  
  <p>However, I do not understand how it works.</p>
  
  <p>From what I've found so far:</p>
  
  <ol>
  <li><code>_</code> has no special meaning in the grammar of Python</li>
  <li><code>_</code> isn't in the <code>chars</code> <code>list</code></li>
  <li>The generator works like <code>(expression(x) for x in iterator)</code></li>
  </ol>
  
  <p>I have tried to further decompose the code in interactive mode and this is what I've found:</p>
  
  <pre><code>In [38]: chars=string.ascii_lowercase + string.digits
  
  In [39]: size=10
  
  In [40]: (random.choice(chars) for _ in range(size))
  Out[40]: &lt;generator object &lt;genexpr&gt; at 0x10bc6b258&gt;
  
  In [41]: list( (random.choice(chars) for _ in range(size))
      ...: )
  Out[41]: ['6', 'v', '3', 'd', 'm', 'c', 'h', '1', 'v', 'n']
  </code></pre>
  
  <p>So my question is how does the <code>random.choice(chars)</code> portion of the generator communicate with the iterative part <code>for _ in range(size)</code> when they have no apparent connection to each other?</p>