1. 程式人生 > >python小結(二) 函式(小白總結)&生成器&迭代器(定義)

python小結(二) 函式(小白總結)&生成器&迭代器(定義)

【def】 

 定義一個函式    f()  呼叫這個函式        f 只是相當於呼叫一個函式物件,返回的是一個函式的記憶體地址,要搞清楚這一點,這樣會對以後高階函式的理解有幫助

def f():
    print "ok"
f()


執行結果:
ok

【引數】

給函式新增引數:1。 普通的引數       2。預設引數    3.不定長引數

【預設引數】

一般預設引數放在最後

def f(name,age=12):
    print "I am {name} I am {age}".format(name=name,age=age)
f("Tom")


執行結果:
I am Tom I am 
12

【不定長引數】

1 無命名的不定長引數   

def add(*args):  #不定引數無命名
    sum = 0
    for i in args:
        sum+=i
    return sum
sum =add(1,2,3,4,5)
print sum


執行結果:
15



#當你新增的是列表時

def a(*args):
    print args
a(*[1,2,3,4])  #####單個新增到元組####


執行結果:

(1, 2, 3, 4)

2。有命名的不定長引數

def login(**kwargs):    #有命名
    print kwargs
    
for i in kwargs: print i login(name="Tom",age=19,sex="man") 執行結果: {'age': 19, 'name': 'Tom', 'sex': 'man'} age name sex def b(**kwargs): print kwargs b(**{"name":"aa"}) ######鍵值對方式新增到字典#### 執行結果: {'name': 'aa'

【return】 

結束函式,返回某個物件

如果未在函式中指定return,那這個函式的返回值為None  

可以返回多個物件 ,預設放到一個元組中

【作用域】

總共可以劃分為Legb

built_in (系統定義)       global(全域性變數)        enclosing(巢狀變數)           local(區域性變數)

count = 10
# count =["1","2"]
def out():
    global count    ##申明全域性變數
    count+=1          ##當全域性變數不可變時,區域性變數不可修改,除非申明全域性變數
    # count.append("3")    ##當是可變的型別時,內部可以對他進行修改
    print count
out()


執行結果:
11

 【高階函式】

高階函式是至少滿足下列一個條件的函式:

1.接受一個或多個函式作為輸入

2.輸出一個函式

def f(n):
    return n*n
def foo(a,b,fn):
    return fn(a)+fn(b)  ####fn()就是執行這個f()函式######
print foo(1,2,f)  ######f就是一個函式的記憶體地址######

def f():
    return 8
def fun():
    return f
ter=fun()     #####只是得到f函式的記憶體地址######
print ter
print ter()   ####只要加上括號就代表執行這個函式,所以就是執行f()這個函式


執行結果:
5
<function f at 0x00000000026CEBA8>
8

【遞迴函式】

定義:簡單的可以概括為:呼叫自己的函式+結束條件

######遞迴求階乘#####

def f(n):
    if n==1:
        return 1
    return n*f(n-1)   #####呼叫自己,結束條件
print f(7)

print reduce(lambda a,b:a*b ,range(1,8))     #之後會講到這幾個重要的內建函式,現在只是瞭解會有更簡單的方法來實現遞迴


執行結果:
5040
5040

【斐波那契數列】

可以很好地解釋遞迴函式,好好理解一下斐波那契數列,後邊會以這個數列來講解生成器

def f(n):
    if n<=2:
        return n
    return f(n-1)+f(n-2)

print f(5)


執行結果:
8

【內建函式】

py2內建函式:https://docs.python.org/3.5/library/functions.html#repr

幾個重要的內建函式:

1。filetr(function,squence)   對sequence中的item依次執行function(item),將執行結果為True的item做成一個filter object的迭代器返回。可以看作是過濾函式。

2。map(function,squence)   對sequence中的item依次執行function(item),將執行結果組成一個map object迭代器返回.map也支援多個sequence,這就要求function也支援相應數量的引數輸入:

3。reduce(function,squence)   對sequence中的item順序迭代呼叫function,如果有starting_value,還可以作為初始值呼叫.

4.。lambda(function,squence)  匿名函式的命名規則,用lamdba 關鍵字標識,冒號(:)左側表示函式接收的引數(a,b) ,冒號(:)右側表示函式的返回值(a+b)。因為lamdba在建立時不需要命名,所以,叫匿名函式  

#filter
str = ["a","b","c","d","e"]
def func(s):
    #print s
    if s !="a":
        return s
let = filter(func,str)
print list(let)

#map
str = [ 'a', 'b']
def fun2(s):
    return s + "alvin"
ret = map(fun2, str)
print(ret)  # map object的迭代器
print(list(ret))  # ['aalvin', 'balvin', 'calvin', 'dalvin']

#reduce
from functools import reduce
def add1(x, y):
    return x + y
print (reduce(add1, range(1, 101)))  ## 5050 (注:1+2+...+100)
print (reduce(add1, range(1, 101), 20))  ## 5070 (注:1+2+...+100+20)

#lambda
#普通函式
def add(a, b):
    return a + b
print add(2, 3)
# 匿名函式
add = lambda a, b: a + b
print add(2, 3)



執行結果:
['b', 'c', 'd', 'e']
['aalvin', 'balvin']
['aalvin', 'balvin']
5070
5

【裝飾器函式】

1.閉包的概念:a)有一個內部函式     b)引用一個外部變數

2.裝飾器的作用:遵守開放,閉合的原則,在不修改原來的程式碼的基礎上新增要求,呼叫的時候重新賦值相當於呼叫原來的函式, 不會影響其他對該函式的呼叫

下面是兩個例子來幫助理解裝飾器,裝飾器再python中十分的重要,如果這兩個例子不能幫助你理解的話,你可以看一下大牛Yuan先生部落格,裡面講的很通徹

例子1:

計算函式執行的時間

import time
def show_time(f):
    def out(*x,**y):
        start = time.time()
        f(*x,**y)
        end = time.time()
        print "spend time:%s"%(end-start)
    return out
@show_time    # f=show_time(f)
def f(*a,**b):
    sums=0
    for i in a:
        sums+=i
    print sums
    time.sleep(1)
f(1,2,7,4)



執行結果:
14
spend time:1.0

例子2

增加難度,再新增一個引數

import time
def log(flag):
    def show_time(f):            #2.show_time(f,flag)
        def out(*x,**y):
            start = time.time()
            f(*x,**y)
            end = time.time()
            run = end-start
            print "spend time:%s"%(run)
            if flag=="True":
                with open("text","a") as ji:
                    ji.write("\nspend time:%s"%(run))
        return out
    return show_time
@log("True")   #@out    out(f) # 1[email protected]封裝的只能傳一個引數,只要滿足閉包的定義就能執行,返回值show_time,就相當於@show_time,
def f(*a,**b):    #2,不用@多加一個引數也可以
    sums=0
    for i in a:
        sums+=i
    print sums
    time.sleep(1)
f(1,2,7,4)



執行結果:

14
spend time:1.00099992752

【列表生成式】

print [ i*i for i in range(0,19)]

執行結果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324]

【生成器(generator)】

生成器其實是一種特殊的迭代器,不過這種迭代器更加優雅

生成器一定是迭代器,迭代器不一定是生成器

生成器的建立:()或 yield

下邊的斐波那契數列會讓你更好的體會生成器,生成器的呼叫時用next()方法,生成器就是平常不會執行,只有呼叫的時候才會執行,而且因為python的回收機制,使得生成器在記憶體中只有自己的一條資料可以更好地對記憶體進行利用

s=((x for x in range(2)))   #yield
print next(s)


執行結果:
0


def fib(max):
    n,before,after = 0,1,1
    while n<max:
       # print after
        yield after   #就成了生成器了
        before,after = after,before+after
        n+=1
a=fib(10)
print next(a)


執行結果:
1

 【生成器的send() 方法】

send()方法是對yeild的前邊的變數進行賦值

def f():
    print "aa"
    count = yield 1
    print count
    yield 2
b = f()
next(b)
ret =b.send("bb")   #可以給yeild前邊的變數賦值
print ret


執行結果:
aa
bb
2

【迭代器】

定義L: 1.有iter方法 2.有next方法

for 內部做的三件事: 1。呼叫可迭代物件的iter方法,返回一個迭代器物件 2.不斷呼叫next方法 3處理StopIteration異常