python函数(day4)

函数

如果定义了一个变量使用了函数的名,可以在使用完变量后,del 变量,释放内存中的变量,使函数可用。

def function_name(arg1,arg2[,...]):
    '''Print sth .

    print the dcostring'''    #文档字符串首行以大写字母开头,句号结尾,第二行空行,第三行开始是详细描述。可以使用__doc__
    statement
[return value]  #return不是必须的,如果没有return则返回none,如果要让函数返回多个值,可以使用元组。

定义函数define

def my_abs(x):                        #多个参数使用逗号分隔
        """this is function use help to show """   #使用print my_abs.__doc__可以打印出这部分doc内容
    if x >= 0:
        return x                       #返回多个值会集合成元祖tuple的形式,若没有return语句则返回None
    else:
        return -x

如果想定义一个什么事也不做的空函数,可以用pass语句:

def nop():
    pass

实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。

默认参数

定义函数的时候,默认参数(一般必选参数在前,默认参数在后),默认参数必须指向不变对象

def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s
print power(x=1,n=3)

可变参数

可以利用可变参数调用,即迭代元祖的值

def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

函数参数中带**,返回字典,若是*返回元组

def t(**kr):
    return kr
print t(a=1,b=2,c=3,d=4)

输出 {'a': 1, 'c': 3, 'b': 2, 'd': 4}

def t(*kr):
    return kr
print t(1,2,3,4)

输出 (1, 2, 3, 4)

关键字参数

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:

def person(name, age, **kw):
    print 'name:', name, 'age:', age, 'other:', kw

输出结果如下

>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

函数组合

函数的参数位置按照 位置匹配=》关键字匹配=》收集元祖参数=》收集匹配的关键字参数

函数的作用域:在函数内部优先使用内部变量,也可以使用全局变量,函数之间的局部变量互不影响。如果函数中的变量使用global则该变量全局可用,大多数名字引用在三个作用域中查找:先局部(Local),次之全局(Global),再次之内置(Build-in)。

a=42
b=13
def foo():
    global a  #a位于全局namespace中
    a=1
    b=2
foo()  #a的值改变了,b没有变

使用函数传入的参数不要是可变类型,可能会影响值,如下示例:

def fun1(arg):
      arg[0]=5
      return arg
print fun1([1,2,3])

结果为[5, 2, 3],其中第一个值被改掉了,需要特别注意

自省与函数 func.__code__
print dir(fun1.__code__)
print fun1.__code__.co_filename

高级特性

Slice 切片

左包含,右不包含,左右值一样,则空

>>> L[0:3]
>>> ['Michael', 'Sarah', 'Tracy']   #从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,步长为1

L = range(100)
L
L[:10]
L[-10:]
L[:10:2]依次取10个数,再每两个取一个

Iteration迭代

任何可迭代对象都可以作用于for循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for循环。
通过collections模块的Iterable类型来判断一个对象是否可迭代
from collections import Iterable
isinstance('abc', Iterable) # str是否可迭代
isinstance([1,2,3], Iterable) # list是否可迭代
isinstance(123, Iterable) # 整数是否可迭代

List Comprehensions列表生成式

print [x * x for x in range(1, 11)]
[x * x for x in range(1, 11) if x % 2 == 0]

Generator 生成器

任何使用yield的函数称为生成器,调用生成器函数将创建一个对象,该对象通过连续调用next()的方法(python3种是__next__())生成结果序列。

def countDown(n):
  print "now counting down!"
  while n > 0:
    yield n
    n -=1
c = countDown(10)
c.next()
c.next()

将列表生成式的[] 变为() ,保存的是算法而不是值

g = (x * x for x in range(10))
g.next()

Generator也是可迭代,所以可以用for进行调用

g = (x * x for x in range(10))  
for n in g:
   print n
def fib(max):                    #define斐波拉契数列
    n, a, b = 0, 0, 1
    while n < max:
        print b
        a, b = b, a + b
        n = n + 1

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b                 #如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator
        a, b = b, a + b
        n = n + 1

生成器是基于处理管道、流或数据流编写程序的一种极其强大的方式。
示例:模拟tail -f

import time
def tail(f):
    f.seek(0,2)    #移动到EOF
    while True:
        line = f.readline()  #尝试读取一个新的文本行
        if not line:         #如果没有内容,暂时休眠并在此尝试
            time.sleep(0,1)
            continue
        yield line

lambda

lambda是一个表达式.它没有名称,存储的也不是代码块,它被用作执行很小的功能,不能在里面使用条件语句
d = lamdba x:x+1
print d(2)
print d(4)

函数式编程

传入函数

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

当我们调用add(-5, 6, abs)时,参数x,y和f分别接收-5,6和abs

map/reduce

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

def f(x):
    return x * x
map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])

[1, 4, 9, 16, 25, 36, 49, 64, 81]

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

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

map和reduce配合

>>> 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]
...
>>> reduce(fn, map(char2num, '13579'))
13579

整理成一个str2int的函数就是:

def str2int(s):
    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]
    return reduce(fn, map(char2num, s))

还可以用lambda函数进一步简化成:

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]

def str2int(s):
    return reduce(lambda x,y: x*10+y, map(char2num, s))

也就是说,假设Python没有提供int()函数,你完全可以自己写一个把字符串转化为整数的函数,而且只需要几行代码!

filter

和map()类似,filter()也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

def is_odd(n):
    return n % 2 == 1

filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])

结果: [1, 5, 9, 15]

sorted

Python内置的sorted()函数就可以对list进行排序
传入自定义的比较函数reversed_cmp,就可以实现倒序排序

Closure 闭包

def f1(a):
def f2(b):
return a+b
return f2

q=f1(10)
print q

转载于:https://www.cnblogs.com/chengwenli/p/7573228.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值