05-抽象(函数)

本文介绍了抽象(函数)的概念,将详细介绍参数(parameter)和作用域(scope)的概念,以及递归(Recursion)的概念及其在程序中的用途。

1.函数概念

1.1 创建函数

def fib(num):
    fibs = [0,1]
    for i in range(num):
        fibs.append(fibs[-2]+fibs[-1])    
        if i==num-1:
            print fibs
fib(8)

1.2 文档化函数

文档字符串:在函数的开头写下字符串,它就会作为函数的一部分进行存储。

>>> def square(x):
>>>    'Calculates the square of the number x.'
>>>    return x*x
>>> square(2)
4
>>> square.__doc__
Calculates the square of the number x.

2 参数

函数中有两类参数:位置参数和关键字参数。

2.1 位置参数

调用函数时根据函数定义的参数位置来传递参数。

# 两个参数的顺序必须一一对应,且少一个参数都不可以
def hello_1(greeting,name):
    print '%s,%s!'% (greeting,name)
hello_1('hello','world')

def hello_2(name,greeting):
    print '%s,%s!'%(name,greeting)
hello_2('hello','world')

2.2 关键字参数

用于函数调用,通过“键-值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。

>>> hello_1(greeting= 'hello',name = 'world')
hello,world!
>>> hello_1(name= 'hello',greeting = 'world')
world,hello!

总结:有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序的

2.3 默认参数

用于定义函数,为参数提供默认值,调用函数时可传可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)

# 正确的默认参数定义方式--> 位置参数在前,默认参数在后
def hello_4(name,greeting='hello',punctuation='!'):
    print '%s,%s%s' % (greeting,name,punctuation)

hello_4('Candy','HELLO','.')

输出如下:

HELLO,Candy.

2.4 可变参数

定义函数时,有时候我们不确定调用的时候会传递多少个参数(不传参也可以)。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。

1.包裹位置参数

我们传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递。

def func(*args):
    ....


# func()
# func(a)
# func(a, b, c)
2.包裹关键值参数
def func(**kargs):
    ....

# func(a=1)
# func(a=1, b=2, c=3)

kargs是一个字典(dict),收集所有关键字参数

2.5 解包裹参数

和*,也可以在函数调用的时候使用,称之为解包裹(unpacking)
1、在传递元组时,让元组的每一个元素对应一个位置参数

使用*号运算符是在调用而不是定义时使用:
Demo1:

def add(x,y): 
    return x+y
params =(1,2)
add (*params)

Demo2:

def print_hello(name, sex):
    print name, sex

# args = ('tanggu', '男')
# print_hello(*args)
# tanggu 男

2、在传递词典字典时,让词典的每个键值对作为一个关键字参数传递给函数


def print_hello(name, sex):
    print name, sex

# args = ('tanggu', '男')
# print_hello(*args)
# tanggu 男

2.6 位置参数、默认参数、可变参数的混合使用

基本原则是:先位置参数,默认参数,包裹位置,包裹关键字(定义和调用都应遵循)
典型应用如下:

def func(name, age, sex=1, *args, **kargs):
    print name, age, sex, args, kargs


# func('tanggu', 25, 2, 'music', 'sport', class=2)
# tanggu 25 1 ('music', 'sport') {'class'=2}

3.作用域(命名空间)

变量存储在作用域(也叫命名空间)中,Python中有两类主要的作用域-全局作用域和局部作用域,学过C语言的同学这点非常好理解。

>>> def foo(): x=42
>>> x=1
>>> foo()
>>> x
1
>>> def output(x):print x
>>> x=1
>>> y=2
>>> output(y)
2

重绑定全局变量

>>> x=1
>>> def change_global():
>>>      global x
>>>      x = x +1
>>>  change_global()
>>> x
2 

4.递归

函数调用本身-递归。

4.1 阶乘和幂

#阶乘
def fac(n):
    if n==0:
        return 1;
    else:
        return n*fac(n-1)
print fac(3)

#幂

4.2 二分查找

5.函数式编程

1.lambda函数

lambda函数也叫匿名函数,即,函数没有具体的名称,而用def创建的方法是有名称的。

1.无参数

如果没有参数,则lambda冒号前面就没有。

#利用def
def foo():return 'beginman'  #Python中单行参数可以和标题写在一行

#用lambda函数
bar = lambda:'beginman'
print bar()      #beginman

#或者直接使用
print lambda:'beginman'
2.有参数

lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右边是返回值。

# 利用def定义
def add(x,y):return x+y

# 利用lambda定义
add2 = lambda x,y:x+y
print add2(1,2)     #3

Python有一些进行函数型编程的机制。包括lambda表达式以及map、filter和reduce函数。

2.filter()函数

filter()函数可以对序列做过滤处理,就是说可以使用一个自定的函数过滤一个序列,把序列的每一项传到自定义的过滤函数里处理,并返回结果做过滤。最终一次性返回过滤后的结果。

>>> def is_odd(x):
>>>    return x % 2 == 1
>>> filter(is_odd, [1, 4, 6, 7, 9, 12, 17])
[1, 7, 9, 17]

>>> import math
>>> def is_sqr(x):
>>>     return math.sqrt(x) % 1 == 0
>>> print filter(is_sqr, range(1, 101))

结果:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

3.map()函数

格式:

map( func, seq1[, seq2…] )

map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。
这里写图片描述

>>> map(str,range(10))
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

这里写图片描述

Python函数式编程之map使用(多个seq)

print map( lambda x, y: ( x * y, x + y), [1, 2, 3], [4, 5, 6] )  # [(4, 5), (10, 7), (18, 9)]

Python函数式编程之map使用(func为None)

#函数为None
# 将多个列表相同位置的元素归并到一个元组,在现在已经有了专用的函数zip()了
print map( None, [1, 2, 3], [4, 5, 6] )  # [(1, 4), (2, 5), (3, 6)]

print zip( [1, 2, 3], [4, 5, 6] )  # [(1, 4), (2, 5), (3, 6)]

map()函数是python内置的高阶函数,对传入的list的每一个元素进行映射,返回一个新的映射之后的list

4.reduce()函数

格式:

reduce( func, seq[, init] )

reduce函数即为化简,它是这样一个过程:每次迭代,将上一次的迭代结果(第一次时为init的元素,如没有init则为seq的第一个元素)与下一个元素一同执行一个二元的func函数。在reduce函数中,init是可选的,如果使用,则作为第一次迭代的第一个元素使用。

这里写图片描述

简单来说,可以用这样一个形象化的式子来说明:

reduce( func, [1, 2,3] ) = func( func(1, 2), 3)

Python函数式编程之reduce使用

n = 5
print reduce(lambda x, y: x * y, range(1, n + 1))  # 120

那么,如果我们希望得到2倍阶乘的值呢?这就可以用到init这个可选参数了。

m = 2
n = 5
print reduce( lambda x, y: x * y, range( 1, n + 1 ), m )  # 240

最好的将map()和reduce()的例子:
http://www.pythoner.com/46.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值