Python 抽象(6) 持续更新

主要学习将语句组织成函数,告诉程序如何做事。

斐波那契数列 (Fibonacci) (任意一个数都是前面两个数之和的序列)

fibs = [0,1];
num = int(raw_input('Input Fibonacci numbers:'))
for i in range(num - 2):
    fibs.append(fibs[-1] + fibs[-2])
print fibs

输出

C:\Users\ChengXu1\Desktop>python aa.py
Input Fibonacci numbers:12
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

创建函数

def hello(name):
    print 'Hello',name

hello('Zhao')

输出

C:\Users\ChengXu1\Desktop>python aa.py
Hello Zhao

函数是否可调用

>>> import math
>>> callable(math.sqrt)
True

在Python3.0中callable废弃了,用hasattr(objectname)代替。

hasattr 判断对象object是否包含名为name的特性。

>>> hasattr(list, 'append')
True 
>>> hasattr(list, 'add')
False

封装 斐波那契数列 函数

def fibs(num):
    result = [0,1];
    for i in range(num - 2):
        result.append(result[-1] + result[-2])
    return result

print fibs(10)
print fibs(13)
C:\Users\ChengXu1\Desktop>python aa.py
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]

无返回值的函数

def fun():
    print 'call 1'
    return
    print 'call 2'

fun()

输出

C:\Users\ChengXu1\Desktop>python aa.py
call 1

函数内遇到 return 直接跳出函数。

函数参数

def语句中 函数括号里面的变量叫形参,调用函数提供的值叫实参。

当函数内部把参数重新赋值的时候,函数外部变量不会受到影响。

def change(num):
    num = 2

num = 1
change(num)
print num

输出

C:\Users\ChengXu1\Desktop>python aa.py
1

下面的变量就会受到影响,因为它们并没有对函数参数赋值,而是对序列元素重新赋值。

def change(numbers):
    numbers[0] = -1

numbers = [1,2]
change(numbers)
print numbers    

输出

C:\Users\ChengXu1\Desktop>python aa.py
[-1, 2]

想要避免出现修改,需要传进去 序列的副本 进去 

def change(numbers):
    numbers[0] = -1

numbers = [1,2]
change(numbers[:])
print numbers    

输出

C:\Users\ChengXu1\Desktop>python aa.py
[1, 2]

判断两个序列是不是独立的,可以这样

>>> numbers = [1,2]
>>> n = numbers[:]
>>> n is numbers
False

判断两个序列值是否相等

>>> numbers = [1,2]
>>> n = numbers[:]
>>> n == numbers
True

关键字参数和默认值

上面使用的函数参数都位置参数,但是位置参数的顺序不容易记住,为了更加简单,使用参数名提供参数称为关键字参数。

def fun(greeting, name):
    print '%s %s' % (greeting, name)

fun(name='Zhao', greeting='Hello')

输出

Hello Zhao

默认值

当函数参数有默认值时,调用的时候,可以提供函数参数,也可以不提供参数。

def fun(greeting='Hello', name='World'):
    print '%s %s' % (greeting, name)

fun()
fun(name='Zhao', greeting='Hello')

输出

Hello World
Hello Zhao

任意参数数量

有的时候需要定义一个类似像print函数一样,参数数量是不固定的,那么就可以这样定义参数。

def print_parameters(*parameters):
    print(parameters)


print_parameters('1', '2', '3')

输出

('1', '2', '3')

星号的作用就是 收集其余的位置参数。

如果需要收集能收集关键字参数的操作,那么就需要两个星号。

def print_parameters(x,**parameters):
    print(x,parameters)


print_parameters(x='1', y='2', z='3')

输出

('1', {'y': '2', 'z': '3'})

参数收集的逆过程

def add(x, y):
    return x + y


parms = (1,2)
print add(*parms)


def print_parameters(x, **parameters):
    print(x, parameters)


parameters = {'y': '2', 'z': '3'}
print_parameters(x='1', **parameters)

输出

3
('1', {'y': '2', 'z': '3'})

作用域

在执行类似x=1赋值语句后,名称x引用到值1,python实际上是 变量和所对应的值用的是一个字典保存的,可以用 vars函数返回这个字典。

x = 1
__dict = vars()
print __dict['x']
__dict['x'] += 1
print x
print __dict['x']

输出

1
2
2

这个字典叫做命名空间或者作用域。除了全局作用域,每次调用函数都会创建一个新的作用域。

def foo():
    x = 99
    print 'Function', x

x = 1
foo()
print 'Global', x

输出

Function 99
Global 1

当全局变量和局部变量,变量名相同时,全局变量就会被局部变量屏蔽,可以用globals函数获取全局变量值(locals返回局部变量的字典)。

def foo():
    x = 99
    print 'Function', x
    space = globals()
    # print 'globals', space
    # print locals()
    space['x'] = 88
    print 'Global Function', space['x']

x = 1
foo()
print 'Global', x

输出

Function 99
Global Function 88
Global 88

重新绑定全局变量

x = 1

def change_global():
    global x
    x += 2

change_global()
print x

输出

3

函数嵌套

def fun1():
    def fun2():
        print 'call fun2'
    fun2()
fun1()

输出

call fun2

函数闭包

def fun1():
    print 'call fun1'
    def fun2():
        return 'call fun2'
    return fun2

print fun1()()

Python 3.0中,nonlocal关键字让户对外部作用域的变量进行赋值(不是全局作用域),使用方法和global关键字一样。

递归

三种实现的阶乘

def factorial(n):
    result = n
    for i in range(n - 1, 0, -1):
        result *= i
    return result

# 36288000
print factorial(10)


def factorial2(n):
    result = n
    for i in range(1, n):
        result *= i
    return result

# 36288000
print factorial2(10)


def factorial3(n):
    if n == 1:
        return 1

    return n * factorial3(n - 1)

print factorial3(10)

递归经典之 二分法查找

def search(a, m):
    lower = 0
    high = len(a) - 1
    while low <= high:
        mid = (low + high) / 2
        midval = a[mid]

        if midval < m:
            low = mid + 1
        elif midval > m:
            high = mid - 1
        else:
            print mid
            return mid
    print -1
    return -1

seq = [34, 67, 100, 200, 300, 95, 94]
seq.sort()
print seq
print search(seq, 100)

import bisect
# 标准库中的二分法查找
print  bisect.bisect(seq, 100)

bisect 是个非常有用的模块,主要是针对数组的插入及排序操作。

相关文档连接

http://www.jb51.net/article/55638.htm

http://www.cnblogs.com/skydesign/archive/2011/09/02/2163592.html

 

Python对于一些”函数式编程“方面的函数 map、filter和reduce函数(Python3.0都迁移到 functools 模块中)

 

map将序列种的元素全部传递给一个函数

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

 

isalnum 判断字符是否为英文字母或数字

filter基于一个函数,进行对元素过滤。

def func(x):
    return x.isalnum()

seq = ['%', '1', 'n']
print filter(func, seq)

还可以这样

seq = ['%', '1', 'n']
print [x for x in seq if x.isalnum()]

# Lambda 表达式 匿名函数
print filter(lambda x: x.isalnum(), seq)

reduce函数 对sequence中的item顺序迭代调用function

>>> def add(x,y): return x + y
>>> reduce(add, range(1, 11))
55

>>> print reduce(lambda x, y : x + y,range(1,11) )
55

print sum(range(1, 11))

 

apply函数

http://wangwei007.blog.51cto.com/68019/1157901

 

posted @ 2016-07-25 14:16  笨重的石头  阅读(107)  评论(0)    收藏  举报