简体   繁体   English

避免 Python 代码 redux 中的代码重复

[英]avoiding code duplication in Python code redux

This is a followup to an earlier question.这是对较早问题的跟进。 I got some good suggestions for that, so I thought I would try my luck again.我得到了一些很好的建议,所以我想我会再试试运气。

from itertools import takewhile

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

af=open('a')
bf=open('b', 'w')
cf=open('c', 'w')

i = 0
if K is None:
    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
            bf.write(out.strip('"')+'\n')
            cf.write(line)
else:
    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
            bf.write(out.strip('"')+'\n')

Is it possible to compactify this code?是否可以压缩此代码? If I have some stuff in common in two loops like this, one obvious possibility is to just factor out the common code, but here, eww.如果我在像这样的两个循环中有一些共同点,一个明显的可能性是只分解公共代码,但是在这里,eww。 The annoying thing is that the only difference here is the writing to c .令人讨厌的是,这里唯一的区别是写入c

Brief summary of code: If K is not None, then loop over K lines of a and write to both b and c .代码简要总结:如果K不是 None,则循环aK行并写入bc Otherwise, loop over all of a and just write to b .否则,遍历所有a并写入b

Why not use only one loop, but including the condition inside that loop?为什么不只使用一个循环,而是包括该循环的条件? Also, you can get rid of the redundancy in that lambda, I think.另外,我认为您可以摆脱 lambda 中的冗余。

from itertools import takewhile

k_is_none = K is None

def illuminacond(x):
    global i
    global K
    result = x.split(',')[0] != '[Controls]'
    if not k_is_none:
        result = result and i < K
    return result

af=open('a')
bf=open('b', 'w')
cf=open('c', 'w')

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
        bf.write(out.strip('"')+'\n')
        if k_is_none:
            cf.write(line)

One check, one loop, no classes, psyco-optimizable.一次检查,一次循环,没有类,心理优化。

from itertools import takewhile

if K is None:
    illuminacond = lambda x: x.split(',')[0] != '[Controls]'
    def action(cf, line): cf.write(line)
else:
    illuminacond = lambda x: x.split(',')[0] != '[Controls]' and i < K
    def action(cf, line): pass

af=open('a')
bf=open('b', 'w')
cf=open('c', 'w')

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
        bf.write(out.strip('"')+'\n')
        action(cf, line)

Why not just:为什么不只是:

from itertools import takewhile

illuminacond = lambda x: x.split(',')[0] != '[Controls]' and (K is None or i<K) #i'm not so sure about this part, confused me a little :).

af=open('a')
bf=open('b', 'w')
cf=open('c', 'w')

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
        bf.write(out.strip('"')+'\n')
        if K is None:
            cf.write(line)

How about this (second class based version)?这个怎么样(第二个基于 class 的版本)?

from itertools import takewhile

class Foo:
    def __init__(self, K = None):
        self.bf=open('b', 'w')
        self.cf=open('c', 'w')
        self.count = 0
        self.K = K

    def Go(self):
        for self.line in takewhile(self.Lamda(), open('a')):
            self.SplitLine()
            if self.IsValidPid():
                self.WriteLineToFiles()

    def SplitLine(self):
        self.lineSplit=self.line.split(',')

    def Lamda(self):
        if self.K is None:
            return lambda x: x.split(',')[0] != '[Controls]'
        else:
            return lambda x: x.split(',')[0] != '[Controls]' and self.count < self.K

    def IsValidPid(self):
        pid=self.lineSplit[1][0:3]
        return pid!='cnv' and pid!='hCV' and pid!='cnv'

    def WriteLineToFiles(self):
        self.count += 1
        self.bf.write(self.ParseLine())
        if self.K is None:
            self.cf.write(self.line)

    def ParseLine(self):
        return (self.lineSplit[1] + ',' + self.lineSplit[2] + ',' + 
                self.lineSplit[3][1] + self.lineSplit[3][3] + ',' +
                self.lineSplit[15] + ',' + self.lineSplit[9] + ',' + 
                self.lineSplit[10]).strip('"')+'\n'

Foo().Go()

Original version:原始版本:

from itertools import takewhile

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

def Parse(line):
    return (line[1] + ',' + line[2] + ',' + line[3][1] + line[3][3] + ',' +
            line[15] + ',' + line[9] + ',' + line[10]).strip('"')+'\n'

def IsValidPid(line_split):
    pid=line_split[1][0:3]
    return pid!='cnv' and pid!='hCV' and pid!='cnv'

bf=open('b', 'w')
cf=open('c', 'w')

def WriteLineToFiles(line, line_split):
    bf.write(Parse(line_split))
    if K is None:
        cf.write(line)

i = 0

for line in takewhile(illuminacond, open('a')):
    line_split=line.split(',')
    if IsValidPid(line_split):
        WriteLineToFiles(line, line_split)
        i += 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM