python递归函数

img


python 递归函数求一个数的阶乘 请问下这个应该怎样答 python递归函数求一个数的阶乘

n * fact(n-1)
阶乘就是n * (n-1) * (n-2) ... 一直乘到1,递归就是将n的阶乘拆分成n乘以n-1的阶乘,而n-1这个数作为新的n,又可以通过之前的方法计算阶乘。

def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)

n = int(input("请输入一个正整数:"))
result = factorial(n)
print("{}的阶乘为:{}".format(n, result))
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7704340
  • 这篇博客你也可以参考下:【初学python】用python做一个简单的超市收银台付款系统
  • 同时,你还可以查看手册:python- 嵌套的列表推导式 中的内容
  • 除此之外, 这篇博客: 使用Python实现梯度下降法处理回归问题中的 使用Python实现梯度下降法处理回归问题 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 我们这将使用[sklearn][6] 框架和手动方式实现梯度下降法对数据的回归操作
    - 使用sklearn 框架
    首先我们要导入sklearn 的包,代码如下:

        import numpy as np
        import pandas as pd
        import matplotlib.pyplot as plt
        import time
        from sklearn.linear_model import LinearRegression,Ridge,LassoCV,RidgeCV,ElasticNetCV
        from sklearn.preprocessing import PolynomialFeatures
        from sklearn.pipeline import Pipeline

    我们导入了sklearn中常用的包,如LinearRegression,用来实现线性回归。

        np.random.seed(0)
        N = 10
        x = np.linspace(0,6,N)+np.random.randn(N)          #随机生成x
        y = 1.8 * x**3 + x**2 + 14*x -7 +np.random.randn(N)#将x映射到y
        x.shape = -1,1                                     #将x,y变成列向量
        y.shape = -1,1

    为了简单起见,我们使用随机产生的简单数据

        plt.figure(figsize=(12,6),facecolor='w')
        x_hat = np.linspace(x.min(),x.max(),num=100)
        x_hat.shape = -1,1
    
        #线性模型
        model = LinearRegression()  #定义好一个线性回归的类
        model.fit(x,y)              #对模型进行拟合
        y_hat = model.predict(x_hat)#预测x_hat相对应的y,命名为y_hat
        s1 = calcRScore(y,model.predict(x))   #calcRScore是手写的评价函数,不是sklearn中的函数,在下面会提出
        print(model.score(x,y))
        print('模块自带输出实现=======================')
        print('参数列表:',model.coef_)
        print('截距:',model.intercept_)

    这样操作之后,我们实现了利用sklearn 的线性回归,画出拟合直线观察:
    这里写图片描述
    - 手动实现梯度下降
    首先我们介绍一下梯度下降法的基本思想,如果要求某个函数的极值,最好的方法就是沿着该函数的梯度方向探寻,如果将函数的梯度记为,则函数 f(x,y)f(x,y)的梯度有下表示:

    f(x,y)=f(x,y)xf(x,y)y∇f(x,y)=(∂f(x,y)∂x∂f(x,y)∂y)

    在数学中,梯度方向可以理解为当前点向极值位置移动最快的点。所以我们在求拟合直线的目标可以看成是求直线的权重 ww,(因为直线方程在广义上的定义: wTx=0wT∗x=0),因此我们使用梯度下降法来更新,
    #手动实现梯度下降法
    def validate(X,Y):                #判断输入X,Y,的数量是否相等
        if(len(X) != len(Y)):
            raise Exception("参数异常")
        else:
            m =len(x[0])             #判断X数据内部特征量是否异常
            for i in X:
                if len(i) !=m:
                    raise Exception("参数异常")
            if len(Y[0]) != 1:        #判断Y
                raise Exception("参数异常")
    def calcDiffe(x,y,a):               #计算损失
        lx = len(x)
        la = len(a)
        if lx ==la:                    #如果权重量和X的行数(也就是数据量)相等
            result = 0
            for i in range(lx):
                result += x[i]*a[i]    #则对应相乘
            return y-result
        elif lx +1 ==la:               #若是不等(X 有偏置,也就是存在常数项)
            result = 0
            for i in range(lx):
                result += x[i]*a[i]
            result +=1*a[lx]           #在对应相乘的基础上加上常数项
            return y-result
        else:
            raise Exception("参数异常")
    def fit(X,Y,alphas,thresh=1e-16,maxIter=20,addConstantItem=True):       #训练函数
        import math
        import numpy as np
        validate(X,Y)
        l = len(alphas)                                                     #alpha数,我们在l个alpha中寻找最好的alpha
        m = len(Y)                                                          #可以理解成数据量
        n = len(x[0])+1 if addConstantItem else len(x[0])                   #X的特征量(当addConstantItem 为True 时,给X 加上偏置量) 
        B = [True for i in range(l)]                                        #判断alpha是否已最优
        J = [np.nan for i in range(l)]                                      #存放对应alpha的损失
        a = [[0 for j in range(n)] for i in range(l)]                       #存放对应alpha的权重(w)
        #开始计算
        for times in range(maxIter):                                                                          
            for i in range(l):                                              #遍历alpha
                if not B[i]:                                                #如果当前alphas已经找到最优值,则不进行计算
                    continue
                ta = a[i]                                                   
                for j in range(n):                                          #遍历特征
                    alpha = alphas[i]        
                    ts = 0  
                    for k in range(m):                                      #遍历数据
                        if j == n -1 and addConstantItem:
                            ts += alpha*calcDiffe(X[k],Y[k][0],a[i])*1      #梯度(无偏置)
                        else:
                            ts += alpha*calcDiffe(X[k],Y[k][0],a[i])*X[k][j]#梯度(有偏置)
                    t = ta[j] +ts                                           
                    ta[j] = t                                                #更新权重
                                                                             #所有特征遍历完毕
                flag = True
                js = 0
                for k in range(m):                                           #这个循环是计算损失
                    js += math.pow(calcDiffe(X[k],Y[k][0],a[i]),2)
                    if js > J[i]:                                            #如果
                        flag = False
                        break
                if flag:
                    J[i] = js
                    for j in range(n):
                        a[j][j] = ta[j]
                else:
                    B[i] = False
            #计算完一个循环,当目标函数小于一个阈值,则结束循环
            r = [0 for j in J if j <= thresh]
            if len(r) >0:
                break
            r = [0 for b in B if not b]
            if len(r)>0:
                break
    
        min_a = a[0]
        min_j = J[0]
        min_alpha = alphas[0]
        for i in range(l):
            if J[i] <min_j:
                min_j = J[i]
                min_a = a[i]
                min_alpha = alphas[i]
        print('最优的alpha值为:',min_alpha)
    
        return min_a
    def predict(X,a):
        Y=[]
        n =len(a) - 1
        for x in X:
            result = 0
            for i in range(n):
                result += x[i]*a[i]
            result += a[n]
            Y.append(result)
        return Y
    def calcRScore(y,py):
        if len(y) != len(py):
            raise Exception("参数异常")
        import math
        import numpy as np
        avgy = np.average(y)
        m = len(y)
        rss = 0.0
        tss = 0
        for i in range(m):
            rss += math.pow(y[i]-py[i],2)
            tss += math.pow(y[i]-avgy,2)
        r = 1.0 - 1.0*rss/tss
        return r
    #自模型
    print('y: ',y)
    ma = fit(x,y,np.logspace(-4,-2,100),addConstantItem=True)
    y_hat2 = predict(x_hat,ma)
    s2 = calcRScore(y,predict(x,ma))
    print('自定义参数==============================')
    print('参数列表',ma)
    
    #开始画图
    plt.plot(x,y,'ro',ms=10,zorder = 3)
    plt.plot(x_hat,y_hat,color='#b624db',lw=2,alpha=0.75,label='thc01 $R:%.3f'%s1,zorder=2)
    # plt.plot(x_hat,y_hat2,color='#6d49b6',lw=2,alpha=0.75,label='thc01 $R:%.3f'%s2,zorder=1)
    plt.legend('upper left')
    plt.grid(True)
    plt.xlabel('X',fontsize=16)
    plt.ylabel('Y',fontsize=16)
    
    plt.suptitle('The Change',fontsize=22)
    plt.show()

    这里写图片描述

  • 您还可以看一下 刘海建老师的Python入门到精通教程课程中的 搭建python的开发环境 和 介绍python的开发工具小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    问题回答: 以下是Python递归函数来计算一个数的阶乘的示例代码:

    def factorial(n):
        if n == 1:
            return 1
        else:
            return n * factorial(n-1)
    

    在这个示例中,如果传入的数字是1,则返回1;否则,返回传入数字乘以递归调用相对于传入数字减1的阶乘。这样就可以递归地计算阶乘了。

    例如,传入数字5,计算阶乘的过程如下:

    factorial(5) = 5 * factorial(4)
                  = 5 * 4 * factorial(3)
                  = 5 * 4 * 3 * factorial(2)
                  = 5 * 4 * 3 * 2 * factorial(1)
                  = 5 * 4 * 3 * 2 * 1
                  = 120
    

    因此,5的阶乘为120。