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. SpringBoot学习------SpringBoot使用Thymleaf模块访问不了静态页面

    SpringBoot使用Thymleaf模块访问不了静态页面 最近学习SpringBoot的过程中使用了Thymeleaf模块引擎,页面发送请求后老是无法显示静态页面,所有的步骤都是参考资料来执行,自 ...

  2. K8S搭建-1 Master 2 Workers(dashboard+ingress)

    本文讲述k8s最新版的搭建(v1.15.2) 分如下几个topic步骤: 各个节点的基本配置 master节点的构建 worker节点的构建 安装dashboard 安装ingress 常见命令 do ...

  3. hdu6703_array

    题意 给定一个1到\(n\)的全排列,两种操作,将\(a_{pos}\)修改为\(a_{pos}+1000000\),询问第一个大于等于\(k\)的且不在\(a_1...a_r\)的数. 分析 由于\ ...

  4. 矩阵微分与向量函数Taylor展开

    参考博客:https://blog.csdn.net/a_big_pig/article/details/78994033

  5. Liunx学习总结(四)--文件的权限管理

    文件和目录的权限 每个文件都有其所有者(u:user).所属组(g:group)和其他人(o:other)对它的操作权限,a:all则同时代表这3者.权限包括读(r:read).写(w:write). ...

  6. 【原创】ARMv8 MMU及Linux页表映射

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  7. sql server创建序列sequence

    1.创建一个序列对象 CREATE SEQUENCE [schema_name . ] sequence_name START WITH <constant> INCREMENT BY & ...

  8. ROS中local costmap的原点坐标系

    local costmap是一个依赖于其他坐标系存在的坐标系统,它并不维护自己的坐标系,而是在另一个坐标系中设定坐标原点,然后记下自己的宽与高.它使用数据结构nav_msgs/OccupancyGri ...

  9. Spring源码解析之ConfigurableApplicationContext

    UML图 接口的作用 从上面的UML图中,可以看到 ConfigurableApplicationContext 直接继承了 ApplicationContext, Lifecycle, Closea ...

  10. 2019 Multi-University Training Contest 2

    2019 Multi-University Training Contest 2 A. Another Chess Problem B. Beauty Of Unimodal Sequence 题意 ...