У меня есть ряд вложенных циклов, которые циклически перебирают несколько файлов Excel и на основе проверок содержимого добавляют содержимое в список фреймов данных.
При определенном условии мне нужно выйти из текущего цикла, не добавлять в список фреймов данных и продолжить синтаксический анализ следующего excel. К сожалению, я не могу понять, как настроить цикл, чтобы добиться желаемого поведения.
В настоящее время код выглядит следующим образом. Я добавил комментарии, объясняющие, какое поведение я ищу.
for name in folder_names:
path = rf'I:\PATH\{name}'
file_list = [f for f in glob.glob(path+"/*.xlsx")]
df_list = []
for f in file_list: #if a break event is triggered, I need to return here.
xl = pd.ExcelFile(f)
if len(xl.sheet_names) == 1:
wb = load_workbook(f, data_only = True)
sh = wb.worksheets[0]
ColNames = {}
Current = 0
for COL in sh.iter_cols(1, sh.max_column):
ColNames[COL[0].value] = Current
Current += 1
for row_cells in sh.iter_rows(min_row=2, max_row=len(sh['D'])):
if row_cells[ColNames['XXXX ID']].fill.start_color.index != '00000000':
path_file.write(f+'\n')
break
df_list.append(pd.read_excel(f)) #if a break event is triggered, I need this line to NOT be executed
Желаемая логика:
Если текущий excel имеет только 1 лист, проверьте, не имеет ли столбец D цвет заливки ячейки, если true, добавьте в список фреймов данных, если false, вернитесь к следующему файлу excel в цикле.
@RufusVS Заявление for ... else ...
сделает эту работу. Просто пропустите добавление, если мы нажмем break
. Так было бы else: df_list.append(...)
и все.
@Asocia Спасибо! Я никогда не использовал конструкцию for..else
в Python, и мне казалось, что здесь она сработает. Но так как я никогда им не пользовался, я не был уверен.
Вы можете добавить логическое значение, чтобы проверить, вышли ли вы из цикла или нет. Это должно выглядеть примерно так (не стесняйтесь менять логическое имя):
for name in folder_names:
path = rf'I:\PATH\{name}'
file_list = [f for f in glob.glob(path+"/*.xlsx")]
df_list = []
for f in file_list: #if a break event is triggered, I need to return here.
xl = pd.ExcelFile(f)
if len(xl.sheet_names) == 1:
wb = load_workbook(f, data_only = True)
sh = wb.worksheets[0]
ColNames = {}
Current = 0
loop_broken = False
for COL in sh.iter_cols(1, sh.max_column):
ColNames[COL[0].value] = Current
Current += 1
for row_cells in sh.iter_rows(min_row=2, max_row=len(sh['D'])):
if row_cells[ColNames['XXXX ID']].fill.start_color.index != '00000000':
path_file.write(f+'\n')
loop_broken = True
break
if (not loop_broken): df_list.append(pd.read_excel(f)) #if a break event is triggered, I need this line to NOT be executed
добавление флага решит это:
flag = False
for x in range(10):
if x == 2:
flag = True
break
if flag:
# dont do sth
pass
else:
# do sth
pass
Вы можете написать заявление for ... else ...
.
for i in range(5):
print(i)
if i > 2:
print("Hit break")
break
else:
print("I didn't hit a break inside the loop")
0 1 2 3 Hit break
for i in range(5):
print(i)
if i > 2:
pass
else:
print("I didn't hit a break inside the loop")
0 1 2 3 4 I didn't hit a break inside the loop
Итак, чтобы ответить на ваш вопрос, вам просто нужно сделать это:
...
for row_cells in sh.iter_rows(min_row=2, max_row=len(sh['D'])):
if row_cells[ColNames['XXXX ID']].fill.start_color.index != '00000000':
path_file.write(f+'\n')
break
else: # <- add this line and indent your code
df_list.append(pd.read_excel(f))
Вам понадобится флаг, потому что break завершает только внутренний цикл. Что-то вроде
keep_file = True
, затем в перерыве используйтеkeep_file = False
, и вы можете поместить свою команду добавления в блокif keep_file
. Или теперь, когда вы находитесь вне цикла, вы можете сделатьif not keep_file: continue
, который переходит к следующей итерации вашегоfor