<p>我有两个非常相似的循环,这两个包含一个非常类似于第三个循环的内部循环(呃。。。:) ). 用代码说明,它看起来很接近:</p>
<pre><code># First function
def fmeasure_kfold1(array, nfolds):
ret = []
# Kfold1 and kfold2 both have this outer loop
for train_index, test_index in KFold(len(array), nfolds):
correlation = analyze(array[train_index])
for build in array[test_index]: # <- All functions have this loop
# Retrieved tests is calculated inside the build loop in kfold1
retrieved_tests = get_tests(set(build['modules']), correlation)
relevant_tests = set(build['tests'])
fval = calc_f(relevant_tests, retrieved_tests)
if fval is not None:
ret.append(fval)
return ret
# Second function
def fmeasure_kfold2(array, nfolds):
ret = []
# Kfold1 and kfold2 both have this outer loop
for train_index, test_index in KFold(len(array), nfolds):
correlation = analyze(array[train_index])
# Retrieved tests is calculated outside the build loop in kfold2
retrieved_tests = _sum_tests(correlation)
for build in array[test_index]: # <- All functions have this loop
relevant_tests = set(build['tests'])
fval = calc_f(relevant_tests, retrieved_tests)
if fval is not None:
ret.append(fval)
return ret
# Third function
def fmeasure_all(array):
ret = []
for build in array: # <- All functions have this loop
relevant = set(build['tests'])
fval = calc_f2(relevant) # <- Instead of calc_f, I call calc_f2
if fval is not None:
ret.append(fval)
return ret
</code></pre>
<p>前两个函数只在方式和时间上不同,它们计算<code>retrieved_tests</code>。第三个函数与前两个函数的内部循环不同,它调用<code>calc_f2</code>,不使用<code>retrieved_tests</code>。你知道吗</p>
<p>实际上,代码更复杂,但是当重复的代码让我恼火的时候,我想我可以接受它。不过,最近我一直在对它进行修改,一次要在两到三个地方进行修改,真烦人。你知道吗</p>
<p>有没有合并重复代码的好方法?我能想到的唯一方法是引入类,它引入了很多样板文件,如果可能的话,我希望保持函数为纯函数。你知道吗</p>
<hr/>
<p><strong>编辑</p>
<p>这是<code>calc_f</code>和<code>calc_f2</code>的内容:</p>
<pre><code>def calc_f(relevant, retrieved):
"""Calculate the F-measure given relevant and retrieved tests."""
recall = len(relevant & retrieved)/len(relevant)
prec = len(relevant & retrieved)/len(retrieved)
fmeasure = f_measure(recall, prec)
return (fmeasure, recall, prec)
def calc_f2(relevant, nbr_tests=1000):
"""Calculate the F-measure given relevant tests."""
recall = 1
prec = len(relevant) / nbr_tests
fmeasure = f_measure(recall, prec)
return (fmeasure, recall, prec)
</code></pre>
<p><code>f_measure</code>计算精度和召回率的<a href="https://en.wikipedia.org/wiki/F1_score" rel="nofollow">harmonic mean</a>。你知道吗</p>
<p>基本上,<code>calc_f2</code>采用了很多快捷方式,因为不需要检索测试。你知道吗</p>