Во-первых, ваша логика может быть упрощена до:
while True:
previous_index = None
for index in idx:
# First iteration
if condition(index) and previous_index is None:
send_email()
previous_index = index
elif condition(index) and previous_index != index:
send_email()
previous_index = index
elif condition(index) and previous_index == index:
# Wait 1 hour
time.sleep(3600)
else:
time.sleep(10) # Wait a bit
continue
Из моей интерпретации вы застреваете, потому что процесс останавливается в течение 1 часа каждый раз, когда он входит в time.sleep(3600)
. Таким образом, в течение этого времени вы хотели бы, чтобы остальная часть цикла продолжала работать с другим индексом.
Проблема в том, что time.sleep()
приостанавливает открытый процесс python в течение указанного времени. Один из способов преодоления этого - открыть дополнительный процесс для отправки электронной почты. Код будет выглядеть следующим образом:
def send_email(previous_index, index):
if previous_index != index or previous_index is None:
# Send the e-mail
else:
# Wait 1 hour
time.sleep(3600)
# Send the e-mail
while True:
previous_index = None
for index in idx:
if condition(index):
Open_process(target = send_email, args = (previous_index, index))
previous_index = index
else:
time.sleep(10) # Wait a bit
continue
Недостаток процессов заключается в том, что они открываются немного медленно. Тем не менее, потоки могут быть лучше, так как вы включили 10-секундную паузу между циклами, я не думаю, что это имеет значение в этом приложении.
Наконец, вы можете посмотреть на многопроцессорность библиотеки для управления процессами.
РЕДАКТИРОВАТЬ:
def send_email(index):
# Function sending the e-mail
print ("e-mail sent")
# Each index is unique and the loop is executed every 10 s
# Key: index; Value: number of iterations; 360 iterations = 1 hour.
tracking = dict()
# Initialize with None
for index in df.index:
tracking[index] = None
while True:
for index in df.index:
if df.loc[index, 'Time flag'] == 1 and tracking[index] is None:
send_email(index)
tracking[index] = 1
elif df.loc[index, 'Time flag'] == 1 and tracking[index] < 360:
tracking[index] += 1
elif df.loc[index, 'Time flag'] == 1 and tracking[index] == 360:
send_email(index)
tracking[index] = 1 # Reset since an e-mail is sent.
else:
# df.loc[index, 'Time flag'] == 0
tracking[index] = None
time.sleep(10)
РЕДАКТИРОВАТЬ 2
def send_email(index):
# Function sending the e-mail
print ("e-mail sent")
# Add column to keep tack of last e-mail send timing
# If the e-mail has never been sent, initialize to Nan, None, or -1
# No idea what is more convenient, but adapt the first if accordingly
df.add_column("Last e-mail sent timing")
while True:
for index in df.index:
if df.loc[index, 'Time flag'] == 1 and df[index, "Last e-mail sent timing"] is None:
send_email(index)
df[index, "Last e-mail sent timing"] = current.time()
elif df.loc[index, 'Time flag'] == 1 and current.time - df[index, "Last e-mail sent timing"] < 1 hour:
# skip
continue
elif df.loc[index, 'Time flag'] == 1 and current.time - df[index, "Last e-mail sent timing"] >= 1 hour:
send_email(index)
df[index, "Last e-mail sent timing"] = current.time()
time.sleep(10)
РЕДАКТИРОВАТЬ 3:
duration_to_wait = 2 # in MINUTES
while True:
for index in df.index:
if df.loc[index,'Time flag'] == 1 and df.loc[df.index[index], "Last_email_sent"] == None:
send_email(index)
df.loc[df.index[index], "Last_email_sent"] = datetime.datetime.now()
elif df.loc[index, 'Time flag'] == 1 and datetime.datetime.now() - df.loc[df.index[index], "Last_email_sent"] < datetime.timedelta(minutes=duration_to_wait):
print('Wait')
print(datetime.datetime.now() - df.loc[df.index[index], "Last_email_sent"])
elif df.loc[index, 'Time flag'] == 1 and datetime.datetime.now() - df.loc[df.index[index], "Last_email_sent"] >= datetime.timedelta(minutes=duration_to_wait):
send_email(index)
df.loc[index, "Last_email_sent"] = datetime.datetime.now()
else:
print('false')
time.sleep(10)