第六章 抽象

6.1 懒惰即美德

6.2 抽象和结构

6.3 创建函数

def:定义函数
内建函数callable:可以用来判断函数是否可调用

>>> import math
>>> x=1
>>> y=math.sqrt
>>> callable(x)
False
>>> callable(y)
True

6.3.1 文档化函数

两种方式:注释、字符串
doc:可以查看函数说明
或者使用help:获得相关信息

>>> def addition(x,y):
...     'Conputer the sum of x and y'
...     #hello
...     return x+y
... 
>>> addition.__doc__
'Conputer the sum of x and y'
>>> help(addition)
Help on function addition in module __main__:

addition(x, y)
    Conputer the sum of x and y

6.3.2 并非真正的函数

不管有没有return,python的函数都会返回值,至少会返回None

6.4 参数魔法

6.4.1 值从哪里来

实参和形参

6.4.2 我能改变参数吗

1.为什么要修改参数

例子:名字的存取

def init(data):
    data['first']={}
    data['middle']={}
    data['last']={}

def lookup(data,label,name):
    return data[label].get(name)

def store(data,full_name):
    names=full_name.split()
    if len(names)==2:names.insert(1,'')
    labels='first','middle','last'

    for label,name in zip(labels,names):
        people=lookup(data,label,name)
        if people:
            people.append(full_name)
        else:
            data[label][name]=[full_name]

Mynames={}
init(Mynames)

store(Mynames,'Robin Hood')
store(Mynames,'Robin Loksy')
store(Mynames,'Mr. Gumby')

print lookup(Mynames,'middle','')

2.如果我的参数不可变呢
可使用列表或者函数返回再赋值

6.4.3 关键字参数和默认值

在调用函数我们可以使用(参数名+值)来回避位置问题

def hello(greeting,name):
    print greeting+','+name
hello(name='jack!',greeting='hello')#参数不受前后顺序的限制

还可以给参数设置默认值

6.4.4 收集参数

带*号的参数:收集剩余位置的参数放在一个元组
如果要处理关键字参数使用**:放在字典

def print_params(x,y,z=3,*pospar,**keypar):
    print x,y,z
    print pospar
    print keypar 
print_params(1,2,3,5,6,7,foo=1,bar=2)

1 2 3
(5, 6, 7)
{'foo': 1, 'bar': 2}

6.4.5 参数收集的逆过程

params={'name':'Sir Robin','greeting':'Well met'}
hell(**params)

元组或列表用:* 字典用:**

6.4.6 练习

6.5 作用域

globals:返回全局变量值
locals:返回局部变量的字典
vars:返回全局变量的字典

嵌套作用域:

def multiplier(factor):
    def multiplyByFactor(number):
        return number*factor
    return multiplyByFactor
>>>double=multiplier(2)
>>>double(5)
>>>10

外层循环返回里层循环,但是并没有调用,它“带着”它的环境

6.6 递归

6.6.1 两个经典:阶乘和幂

#n的阶乘
def factorial(n):
    if n==1:
        return 1
    else: return n*factorial(n-1)
#二分查找
def search(sequence,number,lower,upper):
    if lower==upper:
        assert number==sequence[upper]#检查是否相等,如果这个时候还不相等则找不到,干掉程序,相等返回upper
        return upper
    else:
        middle=(lower+upper)//2
        if number>sequence[middle]:
            return search(sequence,number,middle+1,upper)
        else:
            return search(sequence,number,lower,middle)

函数式编程:
map、filter、reduce
map和filter可以轻易被列表推导式代替,基本没什么大的用处,reduce虽然不能轻易被替代,但是很少用到

>>> number=[1,2,3,4,5,6]
>>> reduce(lambda x,y:x+y,number)
21

首先从列表里取前两个数,然后执行x+y,然后将结果当成x,再从列表里取出一个数当做y,直到列表的数据全被处理

本章新函数

map(func,seq[,seq,…]):对序列中的每个元素应用函数
filter(func,seq):返回其函数为真的元素的列表
reduce(func,seq[,initial]):等同于func(func(seq[0].seq[1]),seq[2]….)
sum(seq):列表求和
apply(func[,args[,kwargs]]):调用函数,参数从元组或字典里取

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章