首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对一种方法的递归效果的好奇

对一种方法的递归效果的好奇
EN

Stack Overflow用户
提问于 2018-03-30 17:38:34
回答 3查看 46关注 0票数 0

我已经编写了一个实例方法,它使用递归找到一个特定的解决方案。它的工作非常好,除了我退出if-elif块的时候。我在IF块中调用函数本身。另外,我只有一条返回语句。这个方法的输出对我来说很奇怪。下面是代码和输出:

代码语言:javascript
复制
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

这是产出:

代码语言:javascript
复制
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语句的时间与执行递归的时间相同。我怎么才能避免这种情况?

我的输出很好。我只想了解这种行为的原因,以及如何避免这种行为。

EN

Stack Overflow用户

发布于 2018-03-30 17:46:38

它打印11次的原因是,您总是在函数的末尾调用print,并且调用该函数11次。(这和你获得Rest of the items are: … 11次的原因是一样的,这一点应该更明显。)

通常,最好的解决方案是重新设计东西,而不是在函数中执行“副作用”(如print ),您只需返回一个值,然后调用方就可以对结果执行它想要的任何副作用。在这种情况下,您调用print 11次并不重要;print只在调用方中发生一次。

如果这是不可能的,您可以更改这一点,以便您只在堆栈顶部时进行print处理。但是,在许多递归函数中,没有明显的方法可以在不传递更多信息的情况下解决这一问题:

代码语言:javascript
复制
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

最后的方法是只包装递归函数,如下所示:

代码语言:javascript
复制
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的实现中,因此您不需要更改调用方看到的接口。)

票数 3
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49578862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档