【Python】小甲鱼课后习题第17、18、19讲--函数(上)

问答题


0. 你有听说过DRY吗?

答:DRY 是程序员们公认的指导原则:Don’t Repeat Yourself.
快快武装你的思维吧,拿起函数,不要再去重复拷贝一段代码了!

1. 都是重复一段代码,为什么我要使用函数(而不使用简单的拷贝黏贴)呢?

答:使用函数:

  1. 可以降低代码量(调用函数只需要一行,而拷贝黏贴需要N倍代码)
  2. 可以降低维护成本(函数只需修改def部分内容,而拷贝黏贴则需要每一处出现的地方都作修改)
  3. 使序更容易阅读(没有人会希望看到一个程序重复一万行“I love FishC.com”)

3*. 创建函数使用什么关键字,要注意什么?

答:使用“def”关键字,要注意函数名后边要加上小括号“()”,然后小括号后边是冒号“:”,然后缩进部分均属于函数体的内容,例如:

def MyFun():
    # 我是函数体
    # 我也是函数体
    # 我们都属于函数 MyFun()

# 噢,我不属于 MyFun()函数的了

4*. 请问这个函数有多少个参数?

def MyFun((x, y), (a, b)):
    return x * y - a * b

答:如果你回答两个,那么恭喜你错啦,答案是0,因为类似于这样的写法是错误的!
我们分析下,函数的参数需要的是变量,而这里你试图用“元祖”的形式来传递是不可行的。

我想你如果这么写,应该是要表达这么个意思:

>>> def MyFun(x, y):
        return x[0] * x[1] - y[0] * y[1]

>>> MyFun((3, 4), (1, 2))
10

5*. 请问调用以下这个函数会打印什么内容?

>>> def hello():
        print('Hello World!')
        return
        print('Welcome To FishC.com!')

答:会打印:

>>> hello()
Hello World!

因为当Python执行到return语句的时候,Python认为函数到此结束,需要返回了(尽管没有任何返回值)。


0. 请问以下哪个是形参哪个是实参?

def MyFun(x):
    return x ** 3

y = 3
print(MyFun(y))

答:x是形式参数(形参),y是实际参数(实参)。
跟绝大部分编程语言一样,形参指的是函数创建和定义过程中小括号里的参数,而实参指的是函数在调用过程中传递进去的参数。

1. 函数文档和直接用“#”为函数写注释有什么不同?

答:给函数写文档是为了让别人可以更好的理解你的函数,所以这是一个好习惯:

>>> def MyFirstFunction(name):
        '函数文档在函数定义的最开头部分,用不记名字符串表示'
        print('I love FishC.com!')

我们看到在函数开头写下的字符串Ta是不会打印出来的,但Ta会作为函数的一部分存储起来,这个我们称之为函数文档字符串,Ta的功能跟注释是一样的。

函数的文档字符串可以按如下方式访问:

>>> MyFirstFunction.__doc__
'函数文档在函数定义的最开头部分,用不记名字符串表示'

另外,我们用help()来访问这个函数也可以看到这个文档字符串:

>>> help(MyFirstFunction)
Help on function MyFirstFunction in module __main__:

MyFirstFunction(name)
函数文档在函数定义的最开头部分,用不记名字符串表示

0*. 下边程序会输出什么?

def next():
    print('我在next()函数里...')
    pre()

def pre():
    print('我在pre()函数里...')
    
next()

答:有些编程语言不够“聪明”,向这类向前引用的方式会导致报错,但Python足够“醒目”,这段代码是正确的!

会输出:

我在next()函数里...
我在pre()函数里...

1*. 请问以下这个函数有返回值吗?

>>> def hello():
        print('Hello FishC!')

如果没有使用return语句指定返回值,Python也不是什么都不返回的,Ta会返回一个None对象,所以我们说Python所有的函数都有返回值。

>>> def hello():
        print('Hello FishC!')

>>> temp = hello()
Hello FishC!
>>> temp
>>> print(temp)
None

2. 请问Python的return语句可以返回多个不同类型的值吗?

答:可以,默认用逗号隔开,是以元祖的形式返回,你当然也可以用列表包含起来返回:

>>> def myFun():
        return '我爱Python', 520, 3.14, True

>>> myFun()
('我爱Python', 520, 3.14, True)
>>> def myFun2():
        return ['小甲鱼', 1314, 5.12, False]

>>> myFun2()
['小甲鱼', 1314, 5.12, False]
>>>

4*. 目测以下程序会打印什么内容?

var = ' Hi '

def fun1():
    global var      #定义全局变量 var
    var = ' Baby '
    return fun2(var)

def fun2(var):
    var += 'I love you'
    fun3(var)
    return var

def fun3(var):
    var = ' 小甲鱼 '

print(fun1())

答:会打印:


baby I love you

小甲鱼建议不到万不得已不要使用全局变量,简洁的概括为:
a) 代码可读性变差
b) 代码安全性降低


动动手


0. 编写一个函数power()模拟内建函数pow(),即power(x, y)为计算并返回x的y次幂的值。

答:代码如下:

def power(x, y):
    result = 1
    
    for i in range(y):
        result *= x

    return result

print(power(2, 3))

1. 编写一个函数,利用欧几里得算法求最大公约数,例如gcd(x, y)返回值为参数x和参数y的最大公约数。

答:欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。
在这里插入图片描述
最大公约数(Greatest Common Divisor)缩写为GCD。代码如下:

def gcd(x,y):
    while True:
        temp=x%y
        if temp==0:
            break
        x=y
        y=temp
    return y

print(gcd(1997,615))

2*. 编写一个将十进制转换为二进制的函数,要求采用“除2取余”的方式,结果与调用bin()一样返回字符串形式。

答:十进制转二进制方法如下:

(1)十进制整数转换为二进制整数采用"除2取余,逆序排列"法。具体做法是:用2整除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数,如此进行,直到商为小于1时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。

(2)十进制小数转换成二进制小数采用"乘2取整,顺序排列"法。具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,此时0或1为二进制的最后一位。或者达到所要求的精度为止。

我的实现代码如下:

def trans(dnum):
    blist=[]
    result=""
    if type(dnum)==int:
        while True:
            temp=dnum%2
            blist.insert(0,temp)
            dnum=dnum//2
            if dnum==0:
                break
        result=str(blist)
        return result
    else:
        print("数据类型错误!")
print(trans(18))

我的代码最后结果输出格式不是字符串类型的, 我查了一下 str() 的用法,发现 str() 会把整个列表转变为字符串包括方括号,就是把 [1,0,0,1,0] 变为"[1,0,0,1,0]"这样。

所以要把列表变为字符串不能只简单的调用一次 str() ,可以学习小甲鱼提供代码中的方法,将列表中的元素一个一个的转变为字符串。

还有就是这个代码没有实现十进制小数转变为二进制的功能。

小甲鱼提供的代码如下:

def Dec2Bin(dec):
    temp = []
    result = ''
    
    while dec:
        quo = dec % 2
        dec = dec // 2
        temp.append(quo)

    while temp:
        result += str(temp.pop())
    
    return result

print(Dec2Bin(62))

0. 编写一个符合以下要求的函数:

a) 计算打印所有参数的和乘以基数(base=3)的结果
b) 如果参数中最后一个参数为(base=5),则设定基数为5,基数不参与求和计算。

答:代码如下:

def mFun(*param, base=3):
    result = 0
    for each in param:
        result += each

    result *= base
    
    print('结果是:', result)

mFun(1, 2, 3, 4, 5, base=5)

该题有一个问题就是:题目没有给出函数形参的具体个数,此前定义的函数形参个数都是明确的,所以这块是一个新东西。

1*. 寻找水仙花数

题目要求:如果一个3位数等于其各位数字的立方和,则称这个数为水仙花数。例如153 = 13+53+3^3,因此153是一个水仙花数。编写一个程序,找出所有的水仙花数。

答:代码如下:

def water_flower():
    for each in range(100,1000):
        a=(each//100)%10      # 注意这里用地板除
        b=(each//10)%10
        c=each%10
        if a**3+b**3+c**3==each:
            print(each)
    
water_flower()

运行结果如下:
在这里插入图片描述
小甲鱼提供的代码如下:

def Narcissus():
    for each in range(100, 1000):
        temp = each
        sum = 0
        while temp:
            sum = sum + (temp%10) ** 3
            temp = temp // 10  # 注意这里用地板除

        if sum == each:
            print(each, end='\t')

print("所有的水仙花数分别是:", end='')
Narcissus()

小甲鱼提供的代码更好,更具一般性。而我写的代码只适合三位数的情况,学习学习!

2. 编写一个函数 findstr()

该函数统计一个长度为 2 的子字符串在另一个字符串中出现的次数。例如:假定输入的字符串为“You cannot improve your past, but you can improve your future. Once time is wasted, life is wasted.”,子字符串为“im”,函数执行后打印“子字母串在目标字符串中共出现 3 次”。
在这里插入图片描述
答:代码如下:

def findstr():
    str2=input("请输入目标字符串: ")
    str3=input("请输入子字符串(两个字符): ")
    sum=0
    for each in range(len(str2)):
        if str2[each]==str3[0]:
            if each ==len(str2)-1:
                break
            elif str2[each+1]==str3[1]:
                sum+=1
            else:
                continue
        else:
            continue
    print(f"子字符串在目标字符串中共出现 {sum} 次")

findstr()                 

0. 编写一个函数,判断传入的字符串参数是否为“回文联”(回文联即用回文形式写成的对联,既可顺读,也可倒读。例如:上海自来水来自海上)

程序执行结果如图:
在这里插入图片描述
答:代码如下:

方法一:

def judge():
    str1=input("请输入一句话: ")
    length=len(str1)
  
    for each in range(int(length//2)):
        if str1[each]==str1[length-1-each]:
            continue
        else:
            print("不是回文联!")
            return
    print("是回文联!")

judge()

方法二:

def palindrome(string):
    list1 = list(string)
    list2 = reversed(list1)
    if list1 == list(list2):
        return '是回文联!'
    else:
        return '不是回文联!'
print(palindrome('上海自来水来自海上'))

1. 编写一个函数,分别统计出传入字符串参数(可能不只一个参数)的英文字母、空格、数字和其它字符的个数。

程序执行结果如图:
在这里插入图片描述
答:代码如下:

def count(*param):
    length = len(param)
    for i in range(length):
        letters = 0
        space = 0
        digit = 0
        others = 0
        for each in param[i]:
            if each.isalpha():
                letters += 1
            elif each.isdigit():
                digit += 1
            elif each == ' ':
                space += 1
            else:
                others += 1
        print('第 %d 个字符串共有:英文字母 %d 个,数字 %d 个,空格 %d 个,其他字符 %d 个。' % (i+1, letters, digit, space, others))
            
count('I love fishc.com.', 'I love you, you love me.')

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早知晓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值