我已经编写了一个实例方法,它使用递归来找到特定的解决方案。它工作得非常好,除了我退出if-elif块的时候。我在IF块中调用函数本身。而且,我只有一个返回语句。这个方法的输出对我来说很奇怪。以下是代码和输出:
def create_schedule(self):
"""
Creates the day scedule for the crew based on the crew_dict passed.
"""
sched_output = ScheduleOutput()
assigned_assignements = []
for i in self.crew_list:
assigned_assignements.extend(i.list_of_patients)
rest_of_items = []
for item in self.job.list_of_patients:
if item not in assigned_assignements:
rest_of_items.append(item)
print("Rest of the items are:", len(rest_of_items))
if len(rest_of_items) != 0:
assignment = sorted(rest_of_items, key=lambda x: x.window_open)[0]
# print("\nNext assignment to be taken ", assignment)
output = self.next_task_eligibility(assignment, self.crew_list)
if len(output) != 0:
output_sorted = sorted(output, key=itemgetter(2))
crew_to_assign = output_sorted[0][1]
assignment.eta = output_sorted[0][4]
assignment.etd = int(assignment.eta) + int(assignment.care_duration)
crew = next((x for x in self.crew_list if x.crew_number == crew_to_assign), None)
self.crew_list.remove(crew)
crew.list_of_patients.append(assignment)
crew.time_spent = assignment.etd
self.crew_list.append(crew)
self.create_schedule()
else:
print("*" * 80, "\n", "*" * 80, "\nWe were not able to assign a task so stopped.\n", "*" * 80, "\n", "*" * 80)
sched_output.crew_output = self.crew_list
sched_output.patients_left = len(rest_of_items)
elif not rest_of_items:
print("Fully solved.")
sched_output.crew_output = self.crew_list
sched_output.patients_left = 0
print("After completely solving coming here.")
return sched_output
这是输出:
Rest of the items are: 10
Rest of the items are: 9
Rest of the items are: 8
Rest of the items are: 7
Rest of the items are: 6
Rest of the items are: 5
Rest of the items are: 4
Rest of the items are: 3
Rest of the items are: 2
Rest of the items are: 1
Rest of the items are: 0
Fully solved.
After completely solving coming here.
After completely solving coming here.
After completely solving coming here.
After completely solving coming here.
After completely solving coming here.
After completely solving coming here.
After completely solving coming here.
After completely solving coming here.
After completely solving coming here.
After completely solving coming here.
After completely solving coming here.
我不明白的是,一旦我的剩余\u项列表为空,我就将数据分配给sched \u输出并返回它。但是,print语句的执行时间与递归执行的时间相同。我怎样才能避免这种情况
我的输出非常好。我只想了解这种行为的原因以及如何避免
在递归函数的末尾有
print("After completely solving coming here.")
。对于每个递归,该行将执行一次考虑这个简单的例子,它再现了您的问题:
现在调用函数:
如您所见,在最后一次调用
foo(x=0)
时,它将打印"Done."
。此时,函数将返回到上一个调用,该调用还将打印"Done."
,依此类推打印11次的原因是,您总是在函数末尾调用
print
,并且您要调用函数11次(这和你得到Rest of the items are: …
11次的原因是一样的,这应该更加明显。)通常,最好的解决方案是重新设计一些东西,这样就不用在函数内部执行
print
之类的“副作用”,只需返回一个值,然后调用方就可以对结果执行它想要的任何副作用。在这种情况下,打print
11次电话并不重要;print
只会在调用者中发生一次如果这是不可能的,您可以更改它,这样当您在堆栈的顶部时,您只需要
print
一些东西。但在许多递归函数中,如果不传递更多信息,就没有明显的方法来解决这个问题:最后一种方法是包装递归函数,如下所示:
通常只有在需要对递归过程进行一次性设置时才需要这样做,但是这里需要进行一次性后处理,这基本上是相同的问题,因此可以用相同的方法解决
(当然,这只是伪装的第一个解决方案,但它隐藏在
create_schedule
的实现中,因此不需要更改调用方看到的接口。)当您在函数完成之前调用自身中的
create_schedule
函数时,一旦它到达末尾,并且不需要再次调用自己,每个函数都会结束,并在函数末尾点击“After completely solving coming here.”这意味着每个函数在调用它自己之后,仍然在运行-只是停留在它调用它自己的那一行-直到它们全部完成,这时暂停的函数可以完成它们的任务,打印出您的语句
相关问题 更多 >
编程相关推荐