我已经编写了一个实例方法,它使用递归找到一个特定的解决方案。它的工作非常好,除了我退出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.我不明白的是,一旦列表rest_of_items为空,我就将数据分配给sched_output并返回它。但是,执行print语句的时间与执行递归的时间相同。我怎么才能避免这种情况?
我的输出很好。我只想了解这种行为的原因,以及如何避免这种行为。
发布于 2018-03-30 17:46:38
它打印11次的原因是,您总是在函数的末尾调用print,并且调用该函数11次。(这和你获得Rest of the items are: … 11次的原因是一样的,这一点应该更明显。)
通常,最好的解决方案是重新设计东西,而不是在函数中执行“副作用”(如print ),您只需返回一个值,然后调用方就可以对结果执行它想要的任何副作用。在这种情况下,您调用print 11次并不重要;print只在调用方中发生一次。
如果这是不可能的,您可以更改这一点,以便您只在堆栈顶部时进行print处理。但是,在许多递归函数中,没有明显的方法可以在不传递更多信息的情况下解决这一问题:
def create_schedule(self, depth=0):
# etc.
self.create_schedule(depth+1)
# etc.
if not depth:
print('After completely solving come here.')
returns sched_output最后的方法是只包装递归函数,如下所示:
def _create_schedule(self):
# etc.
self._create_schedule()
# etc.
# don't call print
return sched_output
def create_schedule(self):
result = self._create_schedule()
print('After completely solving come here.')
return result这通常只有在您需要为递归过程做一些一次性设置时才有必要,但是这里您想要做一些一次性的后处理,这基本上是相同的问题,所以可以用同样的方式解决。
(当然,这只是第一个伪装的解决方案,但它隐藏在create_schedule的实现中,因此您不需要更改调用方看到的接口。)
https://stackoverflow.com/questions/49578862
复制相似问题