python函数

1.函数的参数

  参数有:关键参数(默认参数),无名称参数,有名称参数(字典)

# 参数有严格的顺序要求,由左到右依次是:一般参数,无名称参数(元组),有名称参数(字典)
def print_info(sex,*args,**kwargs):
    print(sex)      # testsex
    print(args)     # (1, 2, 34)
    print(kwargs)   # {'job': 'IT', 'height': 180}
    for i in kwargs:
        print('%s:%s' %(i,kwargs[i]))   # job:IT height:180
print_info('testsex',1,2,34,job='IT',height=180)  
  
# 参数有严格的顺序要求,由左到右依次是:关键参数(默认参数),有名称参数(字典)
def print_info(sex='male',**kwargs):
    print(sex)      # testsex
    print(kwargs)   # {'job': 'IT'}
    for i in kwargs:
        print('%s:%s' %(i,kwargs[i]))   # job:IT
print_info(job='IT') #默认是male
print_info('testsex',job='IT')

2.函数作用域 built_in/global/enclosing(局部作用域,嵌套在父函数中)/local

x=int(2.9)  # built_in
g_count=0   # global

def outer():
    o_count=1   # enclosing
    def inner():
        i_count=2 # local
        print(o_count)

    inner()
    # print(i_count) #只能在inner内部使用
outer()

3.高阶函数

  1)函数有返回值  2) 函数可以作为参数传递

def f(n):
    return n**2
def foo(a,b,func):
    x = func(a) + func(b)
    print(x)
foo(2,3,f)  # 13

4.递归

  1)程序调用自身的编程技巧称为递归

  2)必须指定结束递归的条件

sum = 0
def jiecheng(n):
    global sum
    sum += n
    n -= 1
    if n >= 1:
        return jiecheng(n)
    else:
        print(sum)
jiecheng(5) # 15 计算5+4+3+2+1

  用递归实现斐波拉契数列

# F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
# 前两位数字之和等于下位数
# f(0)=0
# f(1)=1
# f(2)=f(1)+f(0) = 1+0 = 1
# f(3)=f(2)+f(1) = 1+1 = 2
# f(4)=f(3)+f(2) = 2+1 = 3
# f(5)=f(4)+f(3) = 3+2 = 5
def fibo(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibo(n-1)+fibo(n-2)
print(fibo(5)) #5

 5.内部函数

  reduce(func,iterable)

       reduce的工作过程是 :在迭代sequence(tuple ,list ,dictionary, string等可迭代物)的过程中,首先把 前两个元素传给 函数参数,函数加工后,然后把得到的结果和第三个元素作为两个参数传给函数参数, 函数加工后得到的结果又和第四个元素作为两个参数传给函数参数,依次类推

  将可迭代对象按照函数func定义处理

from functools import reduce
def add1(x,y):
    return x+y
ret = reduce(add1,[1,2,3,4])
print(ret)

  sorted(iterable,key=None,reverse=False)

>>> list2 = [{'name':'ss','age':26},{'name':'kk','age':28},{'name':'bb','age':27}]>>> sorted(list2,key=lambda x:x['age'])
[{'name': 'ss', 'age': 26}, {'name': 'bb', 'age': 27}, {'name': 'kk', 'age': 28}]
>>>

6.匿名函数

    不用按照函数的定义方式,但能实现函数的功能。用于

from functools import reduce
ret = reduce(lambda x,y:x+y,[1,2,3,4])
print(ret) # 10 
func = lambda x,y,z:x+y+z
ret = func(2,3,4)
print(ret) # 9

   利用lambda函数对列表排序

      以列表元素中的第二个元素排序

>>> list1 = [(2, 2), (3, 4), (4, 1), (1, 3)]
>>> list1.sort(key=lambda x:x[1])
>>> list1
[(4, 1), (2, 2), (1, 3), (3, 4)]
>>> list2 = [{'name':'ss','age':26},{'name':'kk','age':28},{'name':'bb','age':27}]
>>> list2.sort(key=lambda x:x['age'])
>>> list2
[{'name': 'ss', 'age': 26}, {'name': 'bb', 'age': 27}, {'name': 'kk', 'age': 28}]

7.装饰器

  闭包:外部函数定义的变量,在内部函数中修改后,可以在外面看到修改后变量的内容

def outer():
    x = 5
    def inner():
        nonlocal x
        x += 1
        return x
    return inner

a = outer()
b = a()
print(b) # 6

  装饰器的作用:已经写好的功能函数,不能修改,但需要增加新的扩展功能。即对“修改关闭,对扩展开放”。如想要查看某个函数执行的时间。

import time

# 定义一个获取函数执行时间的函数,传入的参数是某个函数的函数名
def show_time(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print('spend %s' % (end_time - start_time))
    return inner

# @是装饰器的标示,紧接“获取函数执行时间”函数。后面是原函数print_info()。
# @show_time相当于 print_info=show_time(print_info),使用原函数执行后,返回该函数的执行时间
@show_time
def print_info():
    time.sleep(2)
    print('装饰器测试')

print_info() # spend 2.0007832050323486

  装饰器加参数

import time

# 定义一个logger,如果传入参数为flag,则打印“日志记录”
def logger(flag='true'):
    def show_time(func):
        def inner():
            start_time = time.time()
            func()
            end_time = time.time()
            print('spend %s' % (end_time - start_time))
            if flag == 'true':
                print('日志记录')
        return inner
    return show_time

# 装饰器加参数
@logger('true') # 等同于print_info=logger('true')(print_info)
def print_info():
    time.sleep(2)
    print('装饰器测试')

print_info() # 日志记录

8.迭代器

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

  使用可迭代对象有列表,元组,字典等。

  生成迭代器:it = iter(可迭代对象)

  使用迭代器中的值,next(it) 

list = [1,2,3,4,]
for i in list:
    print(i,end=" ") # 1 2 3 4

  可以通过for循环可以打印出元素,是因为先通过iter(list)创建了迭代器,然后通过next(iter(list))打印出来

import sys
list = [1,2,3,4]
it = iter(list)

while True:
    try:
        print(next(it),end=" ") # 1 2 3 4
    except StopIteration:
        sys.exit()

9.生成器

  生成器时一个特殊的迭代器,使用yield关键字表示

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

       函数内部包含有yield关键字,那么函数名()执行的结果就是生成器,并且不会执行函数内部代码,节省内存啊!!!

def func():
    print('====>first')
    yield 1
    print('====>second')
    yield 2
    print('====>third')
    yield 3
    print('====>end')
# g就是生成器也是迭代器
g = func()
print(g) # <generator object func at 0x000001EB700CBF10>

import sys
while True:
    try:
        print(next(g))
        '''
        ====>first
        1
        ====>second
        2
        ====>third
        3
        ====>end
        '''
    except StopIteration:
        sys.exit()

  生成器表达式

g = (x*2 for x in range(1,5))
print(g) # <generator object <genexpr> at 0x00000229DC80BF10>
print(next(g)) # 2
print(next(g))  # 4

  给生成器传值

def foo():
    print("ok")
    count=yield 1
    print(count)

    print("ok2")
    yield 2

    print('ok3')
    yield 3
    
g=foo() #生成器

g.send(None) # 第一次传值没有执行到任何yield,没有接受的对象,传入一个None,此时执行到yeild 1位置
g.send("eeee") # 这次传入"eeee"就是刚才yield 1 执行的位置,将eeee传给了count。然后执行到yeild 2

ret = next(g)
print(ret) # 打印ok3,返回yield 3

    当一个列表中的元素是字典时,想要单独取出时使用生成器如下:

>>> list1 = [{'name':'bobo','type':"ok1"},{'name':'keke','type':'ok2'}]
>>> 
>>> list1
[{'type': 'ok1', 'name': 'bobo'}, {'type': 'ok2', 'name': 'keke'}]
>>> 

>>> ok1 = next(x for x in list1 if x['type']== 'ok1')
>>> ok1
{'type': 'ok1', 'name': 'bobo'}
>>> ok2 = next(x for x in list1 if x['type']== 'ok2')
>>> ok2
{'type': 'ok2', 'name': 'keke'}
>>> 

 

posted @ 2018-07-16 00:46  slitobo  阅读(239)  评论(0)    收藏  举报