title: Ellipsizing list joins, Pythonically
body: <p>I learned about list comprehensions a few days ago, and now I think I&rsquo;ve gone a little crazy with them, trying to make them solve <em>all the problems</em>. Perhaps I don&rsquo;t truly understand them yet, or I just don&rsquo;t know enough Python yet to make them both powerful <em>and</em> simple. This problem has occupied me for a while now, and I&rsquo;d appreciate any input.</p>
  
  <h2>The Problem</h2>
  
  <p>In Python, join a list of strings <code>words</code> into a single string <code>excerpt</code> that satisfies these conditions:</p>
  
  <ul>
  <li>a single space separates elements</li>
  <li>the final length of <code>excerpt</code> does not exceed integer <code>maximum_length</code></li>
  <li>if all elements of <code>words</code> are not in <code>excerpt</code>, append an ellipsis character <code>&hellip;</code> to <code>excerpt</code></li>
  <li>only whole elements of <code>words</code> appear in <code>excerpt</code></li>
  </ul>
  
  <h2>The Ugly Solution</h2>
  
  <pre class="lang-py prettyprint-override"><code>words = ('Your mother was a hamster and your ' +
           'father smelled of elderberries!').split()
  maximum_length = 29
  excerpt = ' '.join(words) if len(' '.join(words)) &lt;= maximum_length else \
            ' '.join(words[:max([n for n in range(0, len(words)) if \
                                 len(' '.join(words[:n]) + '\u2026') &lt;= \
                                 maximum_length])]) + '\u2026'
  print(excerpt)      # Your mother was a hamster…
  print(len(excerpt)) # 26
  </code></pre>
  
  <p>Yup, that works. <code>Your mother was a hamster and</code> fits in 29, but leaves no room for the ellipsis. But boy is it ugly. I can break it up a little:
  </p>
  
  <pre><code>words = ('Your mother was a hamster and your ' +
           'father smelled of elderberries!').split()
  maximum_length = 29
  excerpt = ' '.join(words)
  if len(excerpt) &gt; maximum_length:
      maximum_words = max([n for n in range(0, len(words)) if \
                           len(' '.join(words[:n]) + '\u2026') &lt;= \
                           maximum_length])
      excerpt = ' '.join(words[:maximum_words]) + '\u2026'
  print(excerpt)  # 'Your mother was a hamster…'
  </code></pre>
  
  <p>But now I&rsquo;ve made a variable I&rsquo;m never going to use again. Seems like a waste. And it hasn&rsquo;t really made anything prettier or easier to understand.</p>
  
  <p>Is there a nicer way to do this that I just haven&rsquo;t seen yet?</p>