【发布时间】:2015-02-17 13:33:56
【问题描述】:
我有两个非常相似的循环,这两个包含一个与第三个循环非常相似的内部循环(嗯...:))。用代码说明它看起来接近这个:
# 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
前两个函数只是方式不同,在什么时候计算retrieved_tests。第三个函数与前两个函数的内部循环不同,它调用calc_f2,并且不使用retrieved_tests。
实际上代码更复杂,但虽然重复让我很恼火,但我想我可以忍受它。不过最近一直在改,一次改两三个地方很烦。
如何合并重复的代码?我能想到的唯一方法是引入类,这引入了很多样板文件,如果可能的话,我希望将函数保留为纯函数。
编辑
这是calc_f和calc_f2的内容:
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)
f_measure 计算准确率和召回率的harmonic mean。
基本上,calc_f2 需要很多捷径,因为不需要检索到的测试。
【问题讨论】:
-
calc_f和calc_f2有何不同? -
我编辑了问题以添加有关这些功能的信息。
-
calc_f2接受两个参数(它也使用第二个参数),但fmeasure_all只用一个参数调用它,这真是太棒了。我想这是“简化”代码的结果。 -
是的,对不起。这也是我犹豫是否将该参数设为可选参数的结果。