Python技能树学习-函数

题目一:递归调用

函数的参数:
def dump(index, default=0, *args, **kw):
    print('打印函数参数')
    print('---')
    print('index:', index)
    print('default:', default)
    for i, arg in enumerate(args):
        print(f'arg[{i}]:', arg)
    for key,value in kw:
        print(f'keyword_argument {key}:{value}')
    print('')

if __name__=='__main__':
    dump(0)
    dump(0,2)
    dump(0,2,"Hello","World")
    dump(0,2,"Hello","World", install='Python', run='Python Program')

Python函数的参数十分灵活,例如上面的例子:

index: 按顺序位置指定的参数
default=0: 带有默认值的参数
*args: 0个或多个可选的参数
**kw: 0个或多个关键字参数

查看打印结果可以增加对此的理解,语句 `` 的输出是:

打印函数参数
---
index: 0
default: 2
arg[0]: Hello
arg[1]: World
keyword_argument install:Python
keyword_argument run:Python Program

Python 的函数可以调用别的函数,当调用的是自己本身时,就形成了递归调用。以下是一个待完成的递归调用程序,功能需求是:

  • 循环打印"Hello,World!"的每个字符
  • 循环5次。

# -*- coding: UTF-8 -*-
def circulate_print(str, count=0):
    if count == 5:
        return
    for char in str:
        print(char)
    
    # TODO(You): 请在此完成函数递归调用

if __name__ == '__main__':
    str = "Hello,World!"
    circulate_print(str)

实现

# 第一种
count = count+1
circulate_print(str, count)# 第二种
circulate_print(str, count=count+1)# 第三种
circulate_print(str, count+1)

主要在参数的传递和函数调用的形式上有区别。

  • 第一种实际上改变了count值
  • 第二种用关键字参数形式来传参(将当前count值+1后作为参数传给函数),不会改变count值,要求函数定义中的参数名必须匹配
  • 第三种用位置参数传参,不改变count值

 

错误答案分析 

circulate_print(str, count) 

# 循环时count不改变,陷入死循环

改进 

竖版字母输出更改为横板展示更舒适。

将 print(char) 更改为 print(char,end=' ')

题目二:非递归阶乘实现

0,1,2,3,4,5,6,7,8,9,10! 令人惊讶的是,6个星期的秒数居然也等于10!

不使用函数递归,实现一个阶乘计算函数(n<=170):

# -*- coding: UTF-8 -*-
def fact(n):
    r = 1
    # TODO(You): 请在此编写代码
    return r

if __name__ == '__main__':
    print(fact(10))

实现

# 第一种
for i in range(0, n):r *= (i+1)# 第二种
import math
r = math.factorial(n)# 第三种
while n > 0:r *= nn -= 1
  • 第一种(for循环)和第三种(while循环)在本质上是相似的,都需要手动实现阶乘的计算逻辑,不同之处在于循环的类型和如何索引循环变量。
  • 第二种最优,直接用math库内函数,代码更简洁,且factorial()方法可能经过优化,性能上可能更好。
  • 第三种在循环中直接修改了n的值,如果n的原始值在循环后还需要使用,这种方法可能不适合。

错误答案分析 

import math
z = n + 1
p = [1.000000000190015, 76.18009172947146, -86.50532032941677,
        24.01409824083091, -1.231739572450155, 1.208650973866179E-3, -5.395239384953E-6]

d1 = math.sqrt(2 * math.pi) / z

i = 1
d2 = p[0]
while i <= 6:
    d2 += p[i] / (z + i)
    i += 1

d3d4 = math.pow((z + 5.5), (z + 0.5))*math.exp(-(z + 5.5))
d = d1 * d2 * d3d4
r = int(d)

# 上面三种是直接计算阶乘,而不涉及任何近似或估计。第四种是斯特林近似,用于近似阶乘的数学公式,特别是在处理大数的阶乘时,这个近似公式非常有用。虽然也能运行出同样结果,但是题目给出的n条件是≤170。

 

题目三:函数递归的方式写阶乘计算

# -*- coding: UTF-8 -*-

# TODO(You): 请实现递归计算阶乘

if __name__ == '__main__': print(fact(998))

实现

# 第一种
def inner_fact(n, m):if m == n:return nreturn m*inner_fact(n, m+1)def fact(n):return inner_fact(n,1)# 第二种
def fact(n):if n == 1:return 1return n*fact(n-1)# 第三种
def inner_fact(n, r):if n == 1:return rreturn inner_fact(n-1, r*n)def fact(n):return inner_fact(n, 1)
  • 第一种:inner_fact函数通过递归方式从m增加到n,并在每一步乘以m,缺点是n非常大时容易导致栈溢出。
  • 第二种:从n开始,每次递归调用自己计算n-1的阶乘,直到达到基础情况n == 1。缺点同上。
  • 第三种:利用了尾递归(指递归调用是函数体中的最后一个操作)。inner_fact利用一个额外的参数r来累积结果,每次递归将其乘以n,减少n的值,直到n为1。

错误答案分析 

def inner_fact(n, m, r):
    if m == n:
        return r
    return inner_fact(n, m+1, r*m)


def fact4(n):
    return inner_fact(n, 1, 1)

# 函数名错误

 

题目四:斐波那契

数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子引入了数列0、1、1、2、3、5、8、13、21、34...,称为斐波那契数列(Fibonacci sequence),又称“黄金分割数列”或者“兔子数列”。使用函数递归或非递归的方式都可以方便地计算斐波那契函数:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2)

# -*- coding: UTF-8 -*-

# TODO(You): 请实现递归计算斐波那契函数

if __name__ == '__main__':
    print(fibonacci(6))

实现

# 第一种
def fibonacci(n):if n == 1 or n == 2:return 1r = [1, 1]for i in range(2, n):r[1],r[0] = r[1]+r[0],r[1]return r[1]# 第二种
def fibonacci_inner(n, m, r0, r1):if m == n:return r1return fibonacci_inner(n, m+1, r1, r0+r1)def fibonacci(n):return fibonacci_inner(n, 2, 1, 1)
# 第三种
def fibonacci(n):if n == 1 or n == 2:return 1return fibonacci(n-1) + fibonacci(n-2)
  • 第一种:迭代。r来存储当前计算的两个斐波那契数,然后通过循环更新这两个数直到达到目标位置。计算斐波那契数较大时,最优。
  • 第二种:尾递归。在每一步递归中,只需要更新参数中的值,而不需要保存调用栈。计算斐波那契数不占优势
  • 第三种:递归。计算大量的斐波那契数时,会存在重复计算的问题,效率较低。

错误答案分析 

def fibonacci_inner(n, r):
    if n == 1 or n == 2:
        return r

    return fibonacci_inner(n-1, fibonacci_inner(n-2, r))


def fibonacci4(n):
    return fibonacci_inner(n, 0)

# 函数名错误

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/601834.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力姆泰克医疗电动推杆

力姆泰克医疗电动推杆&#xff0c;宛如医疗领域的精巧舞者&#xff0c;以其卓越的性能和稳定的表现&#xff0c;为众多医疗应用献上了精彩的演绎。它犹如一位敬业的演员&#xff0c;始终保持着高度的灵敏度和精确度&#xff0c;无论是微调还是大幅移动&#xff0c;都能准确无误…

wireshark抓包新手使用教程

Wireshark是非常流行的网络封包分析软件&#xff0c;可以截取各种网络数据包&#xff0c;并显示数据包详细信息。常用于开发测试过程各种问题定位。本文主要内容包括&#xff1a; 1、Wireshark软件下载和安装以及Wireshark主界面介绍。 2、WireShark简单抓包示例。通过该例子学…

好用的AI智能工具:AI写作、AI绘画、AI翻译全都有

在科技不断进步的今天&#xff0c;人工智能&#xff08;AI&#xff09;已经成为我们日常生活中不可或缺的一部分。它不仅在各个领域都有应用&#xff0c;还为我们提供了许多方便快捷的工具。对此&#xff0c;小编今天推荐7款人工智能软件&#xff0c;AI写作、AI绘画、AI翻译全都…

测试开发面经(Flask,轻量级Web框架)

1. Flask的核心特点 a. 轻量级&#xff1a;核心简洁&#xff0c;只提供了基本的功能&#xff0c;其他高级功能可以通过插件或扩展来添加。 b. 灵活性&#xff1a;允许开发者选择适合自己项目的组件和工具&#xff0c;没有强制的项目结构和设计模式。 c. 易于扩展&#xff1a;提…

别再抱怨学鸿蒙没方向了! 这鸿蒙全栈(南北双向)开发学习路线收藏好!

在互联网技术不断发展的现在&#xff0c;鸿蒙操作系统的出现标志着是能技术领域的一次重大突破&#xff0c;鸿蒙作为华为推出的一代操作系统&#xff0c;鸿蒙不仅达代表了自主创新的力量&#xff0c;还因为独特的分布式架构和全场景适配能力而备受关注。随着鸿蒙生态的不断完善…

HarmonyOS 应用开发-边缓存边播放案例

介绍 OhosVideoCache是一个支持边播放边缓存的库&#xff0c;只需要将音视频的url传递给OhosVideoCache处理之后再设置给播放器&#xff0c; OhosVideoCache就可以一边下载音视频数据并保存在本地&#xff0c;一边读取本地缓存返回给播放器&#xff0c;使用者无需进行其他操作…

OneFlow深度学习框架:技术优势与功能特点

文章目录 一、概要二、核心技术优势2.1、分布式训练2.2、极致性能2.3、端到端的智能数据平台2.4、开放灵活的算法支持2.5、跨平台支持 三、功能特点四、OneFlow与TensorFlow对比四、安装OneFlow五、总结 一、概要 OneFlow是一款基于Python的开源深度学习框架&#xff0c;旨在实…

[StartingPoint][Tier1]Pennyworth

Important Jenkins是一个用于自动化构建、测试和部署软件项目的开源持续集成和持续部署&#xff08;CI/CD&#xff09;工具。它允许开发团队自动执行和监控在软件开发过程中的重复性任务&#xff0c;例如构建代码、运行测试、部署应用程序等。Jenkins提供了一个易于使用的Web界…

Go协程池gopool源码解析

1、gopool简介 Repository&#xff1a;https://github.com/bytedance/gopkg/tree/develop/util/gopool gopool is a high-performance goroutine pool which aims to reuse goroutines and limit the number of goroutines. It is an alternative to the go keyword. gopool的…

Astra深度相机在Ubuntu18.04系统下实现相机标定

问题&#xff1a; 当使用Astra相机的启动的指令启动相机后&#xff0c;使用rviz查看相机所发布的rgb数据时&#xff0c;在终端会出现如下的提示信息&#xff1a; Camera calibration file /home/car/.ros/camera_info/rgb_Astra_Orbbec.yaml not found. Camera calibration fil…

HarmonyOS实战开发-如何实现跨应用数据共享实例。

介绍 本示例实现了一个跨应用数据共享实例&#xff0c;分为联系人&#xff08;数据提供方&#xff09;和联系人助手&#xff08;数据使用方&#xff09;两部分&#xff1a;联系人支持联系人数据的增、删、改、查等功能&#xff1b;联系人助手支持同步联系人数据&#xff0c;当…

Dubbo 序列化

Dubbo 序列化 1、什么是序列化和反序列化 序列化&#xff08;serialization&#xff09;在计算机科学的资料处理中&#xff0c;是指将数据结构或对象状态转换成可取用格式&#xff08;例如存成文件&#xff0c;存于缓冲&#xff0c;或经由网络中发送&#xff09;&#xff0c;…