для цикла заканчивается значением «нет»

#python #dataframe #loops #if-statement

Вопрос:

Мой код выполняет создание файла с использованием строк фрейма данных, передаваемых через функцию в цикле. Когда каждая строка обработана, цикл возвращается, что предотвращает полное заполнение всего моего шаблона данными. None

Как остановить этот цикл после обработки всех данных, чтобы избежать получения None последнего результата?

 def template_input_col(df,i):

    col = df['ColumnName'].iat[i]
    dt_type = df['SSISType_src'].iat[i]
    dt_lngh = df['DataTypeLength_src'].iat[i]
    dt_prc = df['DataTypePrecision_src'].iat[i]
    dt_scl = df['DataTypeScale_src'].iat[i]

    input_columns = f'''
    <inputColumn 
        refId="PackageDFTDST.Inputs[DST Input].Columns[{col}]"
        cachedDataType="{dt_type}"
        cachedName="{col}"
        cachedLength="{dt_lngh}"
        cachedPrecision="{dt_prc}"
        cachedScale="{dt_scl}"
        externalMetadataColumnId="PackageDFTDST.Inputs[DST Input].ExternalColumns[{col}]"
        lineageId="PackageDFTSRC.Outputs[SRC Output].Columns[{col}]" />'''

    if dt_type in {'str','wstr','bytes'}:
        input_columns = re.sub(r's*cachedPrecision=".*"', '', input_columns)
        input_columns = re.sub(r's*cachedScale=".*"', '', input_columns)
    elif dt_type in {'numeric'}:
        input_columns = re.sub(r's*cachedLength=".*"', '', input_columns)
    elif dt_type in {'decimal' , 'dbtime2' , 'dbTimeStamp2' , 'dbTimeStampoffset'}:
        input_columns = re.sub(r's*cachedLength=".*"', '', input_columns)
        input_columns = re.sub(r's*cachedPrecision=".*"', '', input_columns)
    else:
        #input_columns = input_columns
        input_columns = re.sub(r's*cachedLength=".*"', '', input_columns)
        input_columns = re.sub(r's*cachedPrecision=".*"', '', input_columns)
        input_columns = re.sub(r's*cachedScale=".*"', '', input_columns)

    return input_columns

def output_input_col():
    for idx, row in df.iterrows():
        if not pd.isna(row['DataTypeName_src']) and not pd.isna(row['DataTypeName_dst']):
            return template_input_col(df,idx)

print(output_input_col())
 

Как только данные будут обработаны, они должны быть введены ниже:

 line = line.replace('<DST_Input_Columns_Placeholder>',  output_input_col())
 

Ожидаемый результат должен сохранять формат:

 <inputColumn
                        refId="PackageDFTDST.Inputs[DST Input].Columns[created_at]"
                        cachedDataType="dbTimeStamp"
                        cachedName="created_at"
                        externalMetadataColumnId="PackageDFTDST.Inputs[DST Input].ExternalColumns[created_at]"
                        lineageId="PackageDFTSRC.Outputs[SRC Output].Columns[created_at]" />
<inputColumn
                        refId="PackageDFTDST.Inputs[DST Input].Columns[updated_at]"
                        cachedDataType="dbTimeStamp"
                        cachedName="updated_at"
                        externalMetadataColumnId="PackageDFTDST.Inputs[DST Input].ExternalColumns[updated_at]"
                        lineageId="PackageDFTSRC.Outputs[SRC Output].Columns[updated_at]" />
<inputColumn
                        refId="PackageDFTDST.Inputs[DST Input].Columns[deleted_at]"
                        cachedDataType="dbTimeStamp"
                        cachedName="deleted_at"
                        externalMetadataColumnId="PackageDFTDST.Inputs[DST Input].ExternalColumns[deleted_at]"
                        lineageId="PackageDFTSRC.Outputs[SRC Output].Columns[deleted_at]" />
 

Комментарии:

1. Там нет никаких return заявлений output_input_col() . Что вы ожидаете напечатать?

2. Может возникнуть некоторая путаница. Ваша функция не возвращается None из-за того, что может быть или не быть последним значением, используемым в for цикле. Он возвращается None , потому что у него нет явного return оператора.

3. template_input_col возвращает строку, но вы ничего не делаете с ней в своем for цикле. Так что весь этот код на самом деле ничего не делает.

4. return выполняет свою работу, но я получаю только последний набор введенных данных, даже если в кадре данных есть 1 строк

5. return завершает функцию, поэтому она останавливает цикл.

Ответ №1:

Если if условие никогда не выполняется для каких-либо строк фрейма данных, функция никогда не выполняет return инструкцию, поэтому она вернется None .

Когда условие истинно, функция останавливается в этой строке кадра данных, так return как завершает функцию.

Если вам нужен список всех шаблонов, добавьте их в список и верните его после цикла.

 def output_input_col():
    results = []
    for idx, row in df.iterrows():
        if not pd.isna(row['DataTypeName_src']) and not pd.isna(row['DataTypeName_dst']):
            results.append(template_input_col(df,idx))
    return results
 

Комментарии:

1. Спасибо, Бармар! Это будет работать, но одна вещь, которую мне нужно сохранить, — это структура каждого блока, созданного при обработке шаблона. Создание списка, который я могу преобразовать обратно в строку, приводит к сбою моего установленного форматирования. Я обновил свое дело с тем, что происходит позже.

2. Я не понимаю, как вы ожидаете, что это сработает. Что вы ожидаете output_input_col() вернуть, чтобы использовать его replace() ? Вторым аргументом должна быть строка.

3. Я поиграл и "n".join(output_input_col()) вернул желаемый результат 🙂 output_input_col() должен был вернуть n-шаблонов, заполненных данными из фрейма данных на строку в указанном формате.