避免Python代码中的代码重复

Fah*_*tha 2 python code-duplication control-flow

请考虑以下Python代码段:

af=open("a",'r')
bf=open("b", 'w')

for i, line in enumerate(af):
    if i < K:
        bf.write(line)
Run Code Online (Sandbox Code Playgroud)

现在,假设我想处理的情况KNone,所以写入继续到文件的末尾.我现在正在做

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
Run Code Online (Sandbox Code Playgroud)

这显然不是解决这个问题的最佳方法,因为我正在复制代码.有没有更集成的方式我可以处理这个?if/break如果K不是None,那自然就是让代码只存在,但这涉及到编写动态的Lisp宏语法,而Python实际上并不是这样做的.为了清楚起见,我并不关心特定情况(我选择的部分原因是它的简单性),而不仅仅是学习我可能不熟悉的一般技术.

更新:在阅读了人们发布的答案并进行更多实验之后,这里有更多的评论.

如上所述,我正在寻找可以推广的一般技术,我认为@Paul的答案,即使用takewhilefrom iterrools,最适合.作为奖励,它也比我上面列出的天真方法快得多; 我不知道为什么.itertools虽然我已经看了好几次,但我并不熟悉.从我的角度来看,这是一个功能性编程For The Win!(有趣的是,itertools曾经有人要求提供有关删除的反馈的作者takewhile.请参阅http://mail.python.org/pipermail/python-list/2007-December/522529.html开头的帖子.)我简化了上面的情况,实际情况有点混乱 - 我正在写循环中的两个不同的文件.所以代码看起来更像:

for i, line in enumerate(af):
    if i < K:
        bf.write(line)
        cf.write(line.split(',')[0].strip('"')+'\n')
Run Code Online (Sandbox Code Playgroud)

鉴于我上传的例子,@Jeff合理建议,在情况下,当KNone,我刚才复制的文件.因为在实践中我无论如何都要循环,这样做并不是一个明确的选择.但是,takewhile对这种情况毫不费力地概括.我还有另一个我在这里没有提到的用例,并且能够在takewhile那里使用,这很好.第二个例子看起来像(逐字)

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)
Run Code Online (Sandbox Code Playgroud)

在这里,我能够使用这个条件

if K is None:
    illuminacond = lambda x: x.split(',')[0] != '[Controls]'
else:
    illuminacond = lambda x: x.split(',')[0] != '[Controls]' and i < K
Run Code Online (Sandbox Code Playgroud)

每个@Paul的原始例子.但是,i尽管代码有效,但我对从外部范围获取的事实并不十分满意.有没有更好的方法呢?或者它应该是一个单独的问题.无论如何,感谢所有回答我问题的人.尊敬的@Jeff,他提出了一些不错的建议.

Aco*_*orn 5

for i, line in enumerate(af):  
    if K is None or i < K:
        bf.write(line)
    else:
        break
Run Code Online (Sandbox Code Playgroud)