python 的学习已经进入到第四天,前面几章我们已经学会了基本的变量操作,以及分支结构和循环结构,那么本章,我们来说说 python 中的函数

1. 函数介绍

在开发程序中,如果需要调用某段代码多次,但是为了 提高编写的效率以及代码的可重用性,所以把具有独立功能的代码块 组织成一个独立的小模块,这就是函数。

在Python 中可以使用 def 关键字来定义函数,和变量一样每个函数也需要声明一个符合命名规范的名称。在函数后面的圆括号内可以放置我们需要传递的参数,待结果执行完毕我们也可以根据需要 使用 return 关键字返回调用结果。

 

案例:

我们先看一道数学题

事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。

如果我们还没有学过函数,我们可以这么写

"""
输入M和N 计算C(M,N)
version:0.1
author:coke
"""
m = int(input('m='))
n = int(input('n='))
fm = 1
for x in range(1,m + 1):
fm *= x
fn = 1
for y in range(1,n + 1):
fn *= y
fmn = 1
for z in range(1,m - n + 1):
fmn *= z
print(fm // fn // fmn)

 

你应该发现了,相似的for循环我们写了三遍,我们是不是可以做一个提取呢?

"""
用函数求分配方案
version: 0.1
author: coke
"""
#-*- coding:utf-8 -*-
def factorial(num):
"""
求阶乘
:param num 非负整数
:return num的阶乘
"""
result = 1
for n in range(1, num + 1):
result *= n
return result m = int(input("请输入一个数字m:"))
n = int(input("请输入一个数字n:"))
print(factorial(m)//factorial(n)//factorial(m-n))

 

2. 函数的参数

函数是绝大多数编程语言中都支持的一个代码的“构建块”,但是Python中的函数与其他语言中的函数还是有很多不太相同的地方,其中一个显著的区别就是Python对函数参数的处理。在Python中,函数的参数可以有默认值,也支持使用可变参数,所以Python并不需要像其他语言一样支持函数的重载 。所以我们定义一个函数时,可以让它有很多不同的使用方式.

from random import randint
def roll_rice(n = 2):
"""
:param n:色子数
:return: n颗色子的点数和
"""
total = 0
for _ in range(n):
total += randint(1,6)
return total
def add(a ,b = 0 ,c=0):
return a + b + c print(roll_rice(1))
print(roll_rice(1))
print(roll_rice(2))
print(roll_rice(2))
# 传递参数时可以不按照设定的顺序进行传递
print(add(c=50, a=100, b=200))

我们给上面两个函数的参数都设定了默认值,这也就意味着如果在调用函数的时候如果没有传入对应参数的值时将使用该参数的默认值,所以在上面的代码中我们可以用各种不同的方式去调用add函数,这跟其他很多语言中函数重载的效果是一致的。

其实上面的add 函数还有更好的实现方法,因为我们可能会 对 0个或多个参数进行加法运算,而具体有几个参数完全可以由调用者决定

#-*-coding:utf-8-*-
# 在参数名前面的*表示args是一个可变参数
# 即在调用add函数时可以传入0个或多个参数
def add(*args):
total = 0
argsType = type(args)
print("args的类型为:%s"%argsType)
for val in args:
total += val
return total print(add())
print(add(1))
print(add(1,2))
print(add(1,2,3))

 

3. 模块与函数

对于任何一种编程语言来说,给变量、函数这样的标识符起名字都是一个让人头疼的问题,因为我们会遇到命名冲突这种尴尬的情况。最简单的场景就是在同一个.py文件中定义了两个同名函数,由于Python没有函数重载的概念,那么后面的定义会覆盖之前的定义,也就意味着两个函数同名函数实际上只有一个是存在的。

"""
测试代码
version:0.1
author:coke
"""
def foo():
print("hello-world") def foo():
print("world-hello")
#下面的代码会输出什么? 是不是有点混乱
foo()

 

当然上面的这种情况我们很容易就能避免,但是如果项目是由多人协作进行团队开发的时候,团队中可能有多个程序员都定义了名为foo的函数,那么怎么解决这种命名冲突呢?答案其实很简单,Python中每个文件就代表了一个模块(module),我们在不同的模块中可以有同名的函数,在使用函数的时候我们通过import关键字导入指定的模块就可以区分到底要使用的是哪个模块中的foo函数,代码如下所示

module1.py

def foo():
print("hello-world")

module2.py

def foo():
print("world-hello")

moduleTest1.py

import module1 as m1
import module2 as m2
#输出 hello-world
m1.foo()
#输出 world-hello
m2.foo()

 

但是如果将代码写成了下面的样子,那么程序中调用的是最后导入的那个foo,因为后导入的foo覆盖了之前导入的foo

moduleTest2.py

from module1 import foo
from module2 import foo # 输出goodbye, world!
foo()

 

需要说明的是,如果我们导入的模块除了定义函数之外还中有可以执行代码,那么Python解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是'__main__'

def foo():
pass
def bar():
pass # _name_ 是Python中一个隐含的变量它代表了模块的名字
# 只有被python解释器直接执行的模块的名字是 __main__
if __name__ == '__main__':
print('call foo')
foo()
print("call bar")
bar

 

4. 递归函数

递归函数:如果一个函数在内部不调用其它的函数,而是自己本身的话,这个函数就是递归函数。

 

举个例子:我们来计算阶乘 n! = 1 * 2 * 3 * ... * n

方案1:循环解决

"""
while 循环算阶乘
version:0.1
author:coke
"""
# -*- coding:utf-8 -*-
def calNum(num):
i = 1
result = 1
while i <= num:
result *= i
i += 1
return result total = calNum(4)
print(total)

 

方案2:递归函数

"""
while 循环算阶乘
version:0.1
author:coke
"""
# -*- coding:utf-8 -*-
def calNum(num):
if num > 1:
result = num * calNum(num - 1)
else:
result = 1
return result total = calNum(4)
print(total)

 

5. 匿名函数

lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。

lambda函数的语法只包含一个语句,如下:

   lambda [arg1 [,arg2,.....argn]]:expression

 

1. 使用匿名函数求两数之和(自己定义函数 )

"""
匿名函数测试
version:0.1
author:coke
"""
def add(a,b):
return a+b result1 = add(1,6)
# 使用lambda 表达式
sum = lambda x,y: x+y
result2 = sum(1,6)
print(result1)
print(result2)

 

2. 数据排序 (作为内置函数的参数 )

"""
匿名函数作为内置函数进行排序
关于 字典和列表的知识点后面会讲
version:0.1
author:coke
"""
stus = [
{"name":"zhangsan", "age":18},
{"name":"lisi", "age":19},
{"name":"wangwu", "age":17}
]
stus.sort(key = lambda x:x['name'])
print(stus)

 

6. 多返回值

在python中 一个函数可不可以返回多个 返回值呢?

"""
多返回值的测试
version:0.1
author:coke
"""
def cal(a,b):
add = a+b
mul = a*b
return add,mul result = cal(2,3)
print(result)

输出结果

 

一个函数,返回多个返回值 ,本质上是利用了元组的特性。

注:关于元组,列表,字典的知识点后面会讲,这里先提一嘴。

Python集训营45天—Day04 (函数)的更多相关文章

  1. Python集训营45天—Day01

    目录 1. Python简介 2. 第一个Python程序 3. 知识点梳理 序言:未来是数据的世界,而python 是一门可以高效简洁处理数据的语言,博主打算花45天左右完成python学习的从0到 ...

  2. Python集训营45天—Day02

    目录 变量和运算符 1.1 初步介绍 1.2 使用案例 1.3 知识点梳理 1.4 练习 序言:这一章我们将学习变量以及常见的类型,我们将以案例和代码相结合的方式进行梳理,但是其中所有的案例和知识点 ...

  3. Python集训营45天—Day03

    目录 1. 分支结构 1.1 初步介绍 1.2 使用案例 1.3 练习 2.循环结构 1.1 初步介绍 1.2 使用案例 1. 分支结构 1.1 初步介绍 至今,我们所写的Python代码都是顺序执行 ...

  4. Python集训营45天—Day08 (文件操作)

    目录 1. 文件操作介绍 2. 文件的读写 2.1 文本文件 2.2 二进制文件 2.3 JSON文件 3. 文件的定位,重命名和删除 4. 文件夹的相关操作 1. 文件操作介绍 大家应该听说过一句话 ...

  5. Python集训营45天—Day07 (面向对象编程进阶)

    目录 1. @property装饰器 2. 魔法方法 3. 类属性和实例属性 4.静态方法和类方法 5. 单继承和多继承 6. 多态 7. del 方法 序言:上个章节我们了解了面向对象的基础知识,这 ...

  6. 2020牛客寒假算法基础集训营2 J.求函数 (线段树 推公式 单点修改 区间查询)

    https://ac.nowcoder.com/acm/contest/3003/J 题解: #include<bits/stdc++.h> typedef long long ll; u ...

  7. 8.10 正睿暑期集训营 Day7

    目录 2018.8.10 正睿暑期集训营 Day7 总结 A 花园(思路) B 归来(Tarjan 拓扑) C 机场(凸函数 点分治) 考试代码 A B C 2018.8.10 正睿暑期集训营 Day ...

  8. 8.5 正睿暑期集训营 Day2

    目录 2018.8.5 正睿暑期集训营 Day2 总结 A.占领地区(前缀和) B.配对(组合) C 导数卷积(NTT) 考试代码 T1 T2 T3 2018.8.5 正睿暑期集训营 Day2 时间: ...

  9. 8.4 正睿暑期集训营 Day1

    目录 2018.8.4 正睿暑期集训营 Day1 A 数对子 B 逆序对 C 盖房子 考试代码 A B C 2018.8.4 正睿暑期集训营 Day1 时间:4.5h(实际) 期望得分:30+50+3 ...

随机推荐

  1. 前端项目优化 -Web 开发常用优化方案、Vue & React 项目优化

    github github-myBlob 从输入URL到页面加载完成的整个过程 首先做 DNS 查询,如果这一步做了智能 DNS 解析的话,会提供访问速度最快的 IP 地址回来 接下来是 TCP 握手 ...

  2. Unity进阶之ET网络游戏开发框架 05-搭建自己的第一个Scene

    版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...

  3. UVA 10098 用字典序思想生成所有排列组合

    题目: Generating permutation has always been an important problem in computer science. In this problem ...

  4. python实现RSA加密和签名以及分段加解密的方案

    1.前言 很多朋友在工作中,会遇到一些接口使用RSA加密和签名来处理的请求参数,那么遇到这个问题的时候,第一时间当然是找开发要加解密的方法,但是开发给加解密代码,大多数情况都是java,c++,js等 ...

  5. 企查查app (二)

    企查查app sign算法破解 已删除!!!! 这次我们又找到设备id,现在就只差aXM这个了. 关注小白公众号,小白带你成长.

  6. [系列] go-gin-api 规划目录和参数验证(二)

    目录 概述 规划目录结构 模型绑定和验证 自定义验证器 制定 API 返回结构 源码地址 go-gin-api 系列文章 概述 首先同步下项目概况: 上篇文章分享了,使用 go modules 初始化 ...

  7. com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect

    com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: con ...

  8. HillCrest Sensor HAL

    1. 抽象定义 Google为Sensor提供了统一的HAL接口,不同的硬件厂商需要根据该接口来实现并完成具体的硬件抽象层,Android中Sensor的HAL接口定义在:hardware/libha ...

  9. Liunx学习总结(二)--目录和文件管理

    之前我们了解了什么是 liunx ,并且认识了它的目录结构,今天我们就来学习下如何进行目录和文件的管理. 创建目录 语法: mkdir [-mp] 目录名称 选项与参数 -m :配置文件的权限喔!直接 ...

  10. 做「容量预估」可没有true和false

    如果第二次看到我的文章,欢迎右侧扫码订阅我哟~