将 for 循环与 Python 中的标志集成的优雅方式

Elegant way of integrating for loop with a flag in Python

我正在使用 click 创建一个命令行工具来执行一些数据预处理。直到现在,我基本上都在使用 click.option() 作为标志并在我的代码中使用一些 if 语句,这样我就可以选择我想要的选项。但是,我正在努力寻找一种优雅的方法来解决我的下一个问题。因为我相信一般的代码结构不取决于我的目的,所以我会尽量做到一般化,而不去深入了解主要代码中的内容。

我有一个元素列表 my_list,我想在每次迭代后循环并应用一些很长的代码。但是,我希望这取决于一个标志(如我所说,通过单击)。一般结构是这样的:

@click.option('--myflag', is_flag=True)
#just used click.option to point out that I use click but it is just a boolean
if myflag: 
    for i in my_list: 
        print('Function that depends on i')
        print('Here goes the rest of the code')
else:
    print('Function independent on i') 
    print('Here goes the rest of the code')

我的问题是我不想将上述结构中的其余代码复制粘贴两次(这是一段很长的代码,很难集成到一个函数中)。有没有办法做到这一点?也就是说,有没有办法告诉 python:“如果 myflag==True,运行 循环进入 mylist 时的完整代码。否则,只需转到完整代码。所有无需复制代码。

编辑:我相信更具体一点实际上可能会有用。

我有的是:

mylist=['washington','la','houston']

if myflag: 
    for i in my_list: 
        train,test = full_data[full_data.city!=i],full_data[full_data.city==i]
        print('CODE:Clean,tokenize,train,performance')
else:
    def train_test_split2(df, frac=0.2):
        # get random sample
        test = df.sample(frac=frac, axis=0,random_state=123)
        # get everything but the test sample
        train = df.drop(index=test.index)
        return train, test
    train, test = train_test_split2(full_data[['tidy_tweet', 'classify']])
    print('CODE: Clean,tokenize,train,performance')

full_data是一个包含文本和分类的pandas数据框。每当我设置 my_flag=True 时,我假装代码在离开一些城市作为测试数据时训练一些模型测试性能。因此,该循环让我大致了解了我的模型在不同城市的表现(某种 GroupKfold 循环)。

在第二个选项下,my_flag=False,有一个随机的测试训练拆分,训练只执行一次。

这是我不想复制的代码部分。

希望对之前的直觉有所帮助

“难以集成到功能中”是什么意思?如果一个功能是一个选项,只需使用以下代码。

def rest_of_the_code(i):
    ...    
if myflag:
    for i in my_list: 
        print('Function that depends on i')
        rest_of_the_code(i)
else:
    print('Function independent on i') 
    rest_of_the_code(0)

否则你可以这样做:

if not myflag:
    my_list = [0] # if you even need to initialize it, not sure where my_list comes from
for i in my_list:     
    print('Function that may depend on i')
    print('Here goes the rest of the code')

编辑以回答您的澄清:您可以使用迭代列表。

mylist=['washington','la','houston']
list_of_dataframes = []
if myflag: 
    for i in my_list: 
        train,test = full_data[full_data.city!=i],full_data[full_data.city==i]
        list_of_dataframes.append( (train, test) )
else:
    train, test = train_test_split2(full_data[['tidy_tweet', 'classify']])
    list_of_dataframes.append( (train, test) )
for train, test in list_of_dataframes:
    print('CODE: Clean,tokenize,train,performance')