title: avoiding code duplication in Python code
body: <p>Consider the following Python snippet:</p>
  
  <pre><code>af=open("a",'r')
  bf=open("b", 'w')
  
  for i, line in enumerate(af):
      if i &lt; K:
          bf.write(line)
  </code></pre>
  
  <p>Now, suppose I want to handle the case where <code>K</code> is <code>None</code>, 
  so the writing continues to the end of the file.
  I'm currently doing </p>
  
  <pre><code>if K is None:
      for i, line in enumerate(af):
          bf.write(line)
  else:
      for i, line in enumerate(af):            
          bf.write(line)
          if i==K:
              break
  </code></pre>
  
  <p>This clearly isn't the best way to handle this, as I'm duplicating the code.
  Is there some more integrated way I can handle this? The natural thing would be
  to have the <code>if/break</code> code only be present if <code>K</code> is not <code>None</code>,
  but this involves writing syntax on the fly a la Lisp macros,
  which Python can't really do. Just to be clear, I'm not concerned about the particular
  case (which I choose partly for its simplicity), so much as learning about general
  techniques I may not be familar with.</p>
  
  <p>UPDATE: After reading answers people have posted, and doing more experimentation, here are some more comments.</p>
  
  <p>As said above, I was looking for general techniques that would be generalizable, and I think @Paul's answer,namely using <code>takewhile</code> from <code>iterrools</code>, fits that best. As a bonus, it is also much faster than the naive method i listed above; I'm not sure why. I'm not really familar with <code>itertools</code>, though I've looked at it a few times. From my perspective this is a case of functional programming <em>For The Win</em>! (Amusingly, the author of <code>itertools</code> once asked for feedback about dropping <code>takewhile</code>. See the thread beginning <a href="http://mail.python.org/pipermail/python-list/2007-December/522529.html" rel="nofollow">http://mail.python.org/pipermail/python-list/2007-December/522529.html</a>.) I'd simplified my situation above, the actual situation is a bit more messy - I'm writing to two different files in the loop. So the code looks more like:</p>
  
  <pre><code>for i, line in enumerate(af):
      if i &lt; K:
          bf.write(line)
          cf.write(line.split(',')[0].strip('"')+'\n')
  </code></pre>
  
  <p>Given my posted example, @Jeff reasonably suggested that in the case when <code>K</code> was <code>None</code>, I just copy the file. Since in practice I am looping anyway, doing so is not such a clear choice. However, <code>takewhile</code> generalizes painlessly to this case. I also had another use case I did not mention here, and was able to use <code>takewhile</code> there too, which was nice. The second example looks like (verbatim)</p>
  
  <pre><code>i=0
  for line in takewhile(illuminacond, af):
      line_split=line.split(',')
      pid=line_split[1][0:3]
      out = line_split[1] + ',' + line_split[2] + ',' + line_split[3][1] + line_split[3][3] + ',' \
                          + line_split[15] + ',' + line_split[9] + ',' + line_split[10]
      if pid!='cnv' and pid!='hCV' and pid!='cnv':
          i = i+1
          of.write(out.strip('"')+'\n')
          tf.write(line)
  </code></pre>
  
  <p>here I was able to use the condition</p>
  
  <pre><code>if K is None:
      illuminacond = lambda x: x.split(',')[0] != '[Controls]'
  else:
      illuminacond = lambda x: x.split(',')[0] != '[Controls]' and i &lt; K
  </code></pre>
  
  <p>per @Paul's original example. However, I'm not completely happy about the fact that I'm getting <code>i</code> from the outer scope, though the code works. Is there a better way of doing this? Or maybe it should be a separate question. Anyway, thanks to everyone who answered my question. Honorable mention to @Jeff, who made some nice suggestions.</p>