六、函数

原创 2018年04月15日 22:11:27

函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

定义一个函数

  • 规则:

1.函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
2. 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。 函数内容以冒号起始,并且缩进。 return [表达式]
3.结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

  • 语法
Python 定义函数使用 def 关键字,一般格式如下:
def 函数名(参数列表):
    函数体
默认情况下,参数值和参数名称是按函数声明中定义的的顺序匹配起来的。
  • 实例
## 输出"Hello World!":

def hello() :
   print("Hello World!")
---------
hello()
Hello World!

带上参数变量:

#!/usr/bin/python3

# 计算面积函数
def area(width, height):
    return width * height

def print_welcome(name):
    print("Welcome", name)

print_welcome("Runoob")
w = 4
h = 5
print("width =", w, " height =", h, " area =", area(w, h))
以上实例输出结果:

Welcome Runoob
width = 4  height = 5  area = 20

函数调用

定义一个函数:给了函数一个名称,指定了函数里包含的参数,和代码块结构。

这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从 Python 命令提示符执行。
如下实例调用了 printme() 函数:

#!/usr/bin/python3

# 定义函数
def printme( str ):
   "打印任何传入的字符串"
   print (str);
   return;

# 调用函数
printme("我要调用用户自定义函数!");
printme("再次调用同一函数");
以上实例输出结果:

我要调用用户自定义函数!
再次调用同一函数
参数传递
在 python 中,类型属于对象,变量是没有类型的:

a=[1,2,3]

a="Runoob"
以上代码中,[1,2,3] 是 List 类型,"Runoob" 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。

Python的作用域一共有4种,分别是:

L (Local) 局部作用域
E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域
B (Built-in) 内建作用域
以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。

迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式。

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter() 和 next()。

字符串,列表或元组对象都可用于创建迭代器:

实例(Python 3.0+)
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
print (next(it))   # 输出迭代器的下一个元素
1
print (next(it))
2

迭代器对象可以使用常规for语句进行遍历:
实例(Python 3.0+)
#!/usr/bin/python3

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:
    print (x, end=" ")
执行以上程序,输出结果如下:

1 2 3 4

也可以使用 next() 函数:

#!/usr/bin/python3

import sys         # 引入 sys 模块

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象

while True:
    try:
        print (next(it))
    except StopIteration:
        sys.exit()
执行以上程序,输出结果如下:

1
2
3
4

生成器

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next()
方法时从当前位置继续运行。

调用一个生成器函数,返回的是一个迭代器对象。

以下实例使用 yield 实现斐波那契数列:

#!/usr/bin/python3

import sys

def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成

while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()
执行以上程序,输出结果如下:

0 1 1 2 3 5 8 13 21 34 55

高阶函数

把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

abs()

abs()方法/函数返回x的绝对值 - x和零之间的(正)的距离。

def add(x, y, f):
    return f(x) + f(y)
##当我们调用add(-5, 6, abs)时,参数x,y和f分别接收-5,6和abs,根据函数定义
add(-5, 6, abs)
11

map()

map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

  • 实例
def f(x):
     return x * x
print(list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])))
[1, 4, 9, 16, 25, 36, 49, 64, 81]

python3想得到列表,得用list() 转换否者得到是map对象

map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把这个list所有数字转为字符串:

print(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']

reduce()

reduce把一个函数作用在一个序列[x1, x2,
x3…]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,

  • 效果
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
  • 序列求和
from functools import reduce
def add(x, y):
    return x+y
print(reduce(add, [1, 3, 5, 7, 9]))
-------------- 
25
  • 把序列[1, 3, 5, 7, 9]变换成整数13579
from functools import reduce

def fn(x, y):
  return x * 10 + y
print(reduce(fn, [1, 3, 5, 7, 9]))
-------------
13579
  • 把str转换为int的函数
def fn(x, y):
    return x * 10 + y
def char2num(s):
    return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
print(reduce(fn, map(char2num, '13579')))
---------
13579

filter()

把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

  • 保留奇数
def add(n):
    return n % 2 == 1
print(list(filter(add, [1,2,3,4,5,6,7,8,9])))
--------
[1, 3, 5, 7, 9]
  • 去空格
def dellnone(s):
    return s and  s.strip()
print(list(filter(dellnone, ['A','',None,'C','','BA'])))

sorted

sorted() 函数对所有可迭代的对象进行排序操作。

sort 与 sorted 区别:

sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。

list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的
list,而不是在原来的基础上进行的操作。

  • 语法

## sorted 语法:
sorted(iterable, key=None, reverse=False)  
##  参数说明:
iterable -- 可迭代对象。
key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
返回值
返回重新排序的列表。
  • 实例

sorted([5, 2, 3, 1, 4])
[1, 2, 3, 4, 5]                      # 默认为升序
  • 利用key进行倒序排序
example_list = [5, 0, 6, 1, 2, 7, 3, 4]
result_list = sorted(example_list, key=lambda x: x*-1)
print(result_list)
------------------------
[7, 6, 5, 4, 3, 2, 1, 0]
  • 要进行反向排序,也通过传入第三个参数 reverse=True:
example_list = [5, 0, 6, 1, 2, 7, 3, 4]
sorted(example_list, reverse=True)
[7, 6, 5, 4, 3, 2, 1, 0]
  • 字符串排序
print(sorted(['bob', 'about', 'Zoo', 'Credit']))
['Credit', 'Zoo', 'about', 'bob']

默认情况下,对字符串排序,是按照ASCII的大小比较的,由于’Z’ < ‘a’,结果,大写字母Z会排在小写字母a的前面。

匿名函数

当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。

  • 直接传入匿名函数
print(list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])))
----------
[1, 4, 9, 16, 25, 36, 49, 64, 81]
##实际上就是:
def f(x):
    return x * x
  • 也可以把匿名函数赋值给一个变量,再利用变量来调用该函数
f = lambda x:x*x
print(f(5))
  • 也可以把匿名函数作为返回值返回
def build(x, y):
    return lambda: x * x + y * y

百度推广教程(六)

《网络营销师-SEM精品课265课》,网络营销思路、方法与实战攻略。
  • 2017年03月16日 09:36

【测绘专用】四舍六入五成双的C++实现

作为一名测绘专业的学生,在内业计算中经常遇到遇到小数点后保留几位小数的问题。根据《工程测量实验教程》(王宇会 著)一书,内业计算按“四舍六入,五前单进双舍(或称奇进偶不进)”的取舍规则进行尾数的取舍。...
  • qq_34844814
  • qq_34844814
  • 2018-01-31 16:59:27
  • 205

SqlServer2005 四舍六入 四舍六入五成双 函数

SqlServer2005 用到了四舍六入五成双,结果网上找了下,没一个能行的。da
  • ssq111
  • ssq111
  • 2014-11-07 10:09:59
  • 591

自己写的sql server四舍六入奇进偶不进的函数

  • 2011年05月15日 00:39
  • 1KB
  • 下载

Excel中的四舍六入五成双

我们都知道四舍五入是一种精确的计数保留法,但是他就是最精确,最能得到我们想要的吗?反正我之前认为他是可以的,但是今天企业要求我们用了一种新得保留方法,四舍六入五成双,他是一种比较精确比较科学的计数保留...
  • gaibian0823
  • gaibian0823
  • 2016-01-26 19:24:56
  • 1940

常用需求系列——4舍6入5成双

// 4舍6入5成双 modf+floor法 double get4s6r(double num){ if (num
  • jishan7
  • jishan7
  • 2016-09-13 15:02:59
  • 144

【设计模式】——六芒星

设计模式这本书已经看完了,但是感觉自己对于这本书的理解还是“不识庐山真面目,只缘身在此山中”的感觉,在看书的过程中就属开始看和最后看的时候纠结了。刚开始时,还没有感觉,理解前两个模式就费了大劲;看过一...
  • u013045214
  • u013045214
  • 2015-03-08 11:19:34
  • 1105

四舍六入!

四舍五入这种方法小学的时候就学过,它虽然简单,但是产生误差累计的因素还是很明显的。就拿保留整数来说:小数部分从0.0~0.4999,是属于“舍”的范围,产生的误差就是0.0~0.4999;而小数部分0...
  • baidu_33836580
  • baidu_33836580
  • 2016-01-25 11:46:40
  • 1372

在Excel中自定义四舍六入函数Round46()

在水文计算中经常利用四舍六入法来进行近似计算,Excel中有一个四舍五入函数Round(),而没有四舍六入函数,为此编写了一个四舍六入函数以方便水文计算时使用。 一、四舍六入函数代码 '=...
  • csdm_cjm
  • csdm_cjm
  • 2015-02-16 12:00:00
  • 509

JAVA中Math.round负数的“五舍六入”

Math.round(-5.4)得到的结果是:-5 Math.round(-5.5)得到的结果是:-5 Math.round(-5.6)得到的结果是:-6Math.round(x);返回x最接近的...
  • zhangfengwu2014
  • zhangfengwu2014
  • 2016-04-11 10:54:21
  • 2527
收藏助手
不良信息举报
您举报文章:六、函数
举报原因:
原因补充:

(最多只允许输入30个字)