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

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

time 鍵值 gen log 元組 默認 增加 http 特殊

【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.@封裝的只能傳一個參數,只要滿足閉包的定義就能運行,返回值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異常

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