Python迭代器仑乌、裝飾器

一、迭代器

1.可迭代對象

可迭代對象【實(shí)體】:可以直接作用于for循環(huán)的實(shí)體【Iterable】

可以直接作用于for循環(huán)的數(shù)據(jù)類型:

? a.list,tuple,dict,set,string

? b.generator【() 和yield】

isinstance:判斷一個實(shí)體是否是可迭代的對象

代碼演示:

#一贸弥、可迭代對象

#1.導(dǎo)入
from  collections  import  Iterable

#2.使用isinstance(數(shù)據(jù)迈螟,Iterable)
print(isinstance([],Iterable))
print(isinstance((),Iterable))
print(isinstance({},Iterable))
print(isinstance((x for x in range(10)),Iterable))
print(isinstance("hello",Iterable))

print(isinstance(10,Iterable))   #False
print(isinstance(True,Iterable))  #False

print("****88")

2.迭代器

不但可以作用于for循環(huán),還可以被next函數(shù)遍歷【不斷調(diào)用并返回一個元素猬膨,直到最后一個元素被遍歷完成角撞,則出現(xiàn)StopIteration】

目前為止,只有生成器才是迭代器【Iterator】

結(jié)論:迭代器肯定是可迭代對象勃痴,但是谒所,可迭代對象不一定是迭代器

isinstance:判斷一個實(shí)體是否是迭代器

代碼演示:

#二、迭代器
from  collections  import  Iterator

print(isinstance([],Iterator))
print(isinstance((),Iterator))
print(isinstance({},Iterator))
print(isinstance("hello",Iterator))
print(isinstance((x for x in range(10)),Iterator))   #True

print("****88")

3.可迭代對象和迭代器之間的轉(zhuǎn)換

可以將可迭代對象轉(zhuǎn)換為迭代器:iter()

代碼演示:

#三沛申、雖然list劣领、tuple、dict铁材、set尖淘、string都不是迭代器
#iter():將list、tuple著觉、dict村生、set、string的  Iterable轉(zhuǎn)換為Iterator
print(isinstance(iter([]),Iterator))
print(isinstance(iter(()),Iterator))
print(isinstance(iter({}),Iterator))
print(isinstance(iter("hello"),Iterator))

總結(jié):

? a.凡是可以作用于for循環(huán)的對象都是Iterable類型

? b.凡是可以作用于next函數(shù)的對象都是Iterator類型

? c.list/tuple/dict/set/string都不是Iterator饼丘,可以通過iter()獲得一個Iterator對象

【面試題】

區(qū)分可迭代對象和迭代器

三趁桃、裝飾器

1.案例

代碼演示:

def test():
    print("拼搏到無能為力,堅持到感動自己")


f = test()  #變量可以指向指向函數(shù)肄鸽,函數(shù)名也是一個變量卫病,所以變量可以當(dāng)做函數(shù)調(diào)用
f()


#思考問題:test增加功能,但是不能修改test函數(shù)內(nèi)部----->裝飾器

在代碼運(yùn)行期間典徘,可以動態(tài)增加函數(shù)功能的方式忽肛,被稱為裝飾器【Decorator】

也就是說,在不修改原函數(shù)的基礎(chǔ)上烂斋,給原函數(shù)增加功能

好處:在團(tuán)隊開發(fā)中屹逛,如果兩個或者兩個以上的程序員會用到相同的功能,但是功能又有細(xì)微的差別汛骂,采用裝飾器:相互不影響罕模,代碼簡化

2.使用

2.1簡單裝飾器

代碼演示:

#1.簡單的裝飾器
def test():
    print("拼搏到無能為力,堅持到感動自己")

#a.書寫閉包
#b.給外部函數(shù)設(shè)置參數(shù),fun表示的是原函數(shù)
def outer(fun):
    def inner():
        # d.給原函數(shù)增加功能
        print("hello")

        #c.調(diào)用原函數(shù)
        fun()

    return inner

#e.使用閉包
f = outer(test)   #f = inner
f()   #inner()

#注意:增加的功能可以寫在原函數(shù)調(diào)用的前面或者后面
#注意:outer函數(shù)就被稱為裝飾器


#練習(xí):給下面的函數(shù)添加功能帘瞭,打印九九乘法表
def show():
    for i in range(10):
        print(i)

def outer1(fun):
    def inner1():
        fun()
        for i in range(1,10):
            for j in range(1,i + 1):
                print("%dx%d=%d"%(j,i,i * j),end=" ")
            print("")
    return  inner1

f1 = outer1(show)
f1()
2.2有參數(shù)的裝飾器

代碼演示:

#2.原函數(shù)有參數(shù)的裝飾器
def getAge(age):
    print(age)

getAge(10)
getAge(-5)

print("************")

#需求:在不修改原函數(shù)的基礎(chǔ)上淑掌,進(jìn)行數(shù)據(jù)的過濾:當(dāng)用戶輸入age為負(fù)數(shù)的時候,則置為0
def wrapper(fun):
    #注意:當(dāng)原函數(shù)有參數(shù)蝶念,裝飾器的作用是為了操作原函數(shù)中的參數(shù)抛腕,給inner設(shè)置參數(shù)
    def inner(num):
        #增加新功能:過濾負(fù)數(shù)
        if num < 0:
            num = 0

        #調(diào)用原函數(shù)
        fun(num)  #age = num
    return  inner

f = wrapper(getAge)
f(10)   #num = 10
f(-5)
2.3系統(tǒng)的簡寫

代碼演示:

#3.簡化demo2中的操作:@裝飾器的名稱  應(yīng)用到原函數(shù)中

#需求:在不修改原函數(shù)的基礎(chǔ)上芋绸,進(jìn)行數(shù)據(jù)的過濾:當(dāng)用戶輸入age為負(fù)數(shù)的時候,則置為0
def wrapper(fun):
    #注意:當(dāng)原函數(shù)有參數(shù)担敌,裝飾器的作用是為了操作原函數(shù)中的參數(shù)摔敛,給inner設(shè)置參數(shù)
    def inner(num):
        #增加新功能:過濾負(fù)數(shù)
        if num < 0:
            num = 0

        #調(diào)用原函數(shù)
        fun(num)  #age = num
    return  inner

#將wrapper裝飾器應(yīng)用在了getAge函數(shù)上,
@wrapper
def getAge(age):
    print(age)

getAge(10)
getAge(-5)

"""
@wrapper

等價于 f = wrapper(getAge)
f(10)   #num = 10

#注意;當(dāng)使用@的時候全封,在同一個文件中马昙,裝飾器必須出現(xiàn)的原函數(shù)的前面

"""
2.4不定長參數(shù)的裝飾器

代碼演示:

#4.不定長參數(shù)的裝飾器

#應(yīng)用場景:當(dāng)同一個裝飾器作用于不同函數(shù)的時候,這些函數(shù)的參數(shù)的個數(shù)是不相同的
def wrapper(fun):
    def inner(*args):
        print("hello")

        fun(*args)   #a = args[0]   b = args[1]

    return  inner

@wrapper
def fun1(a,b):
    print(a + b)

@wrapper
def fun2(a,b,c,d):
    print(a,b,c,d)

fun1(10,20)   #args = (10,20)
fun2(1,2,3,4)
2.5多個裝飾器作用于同一個函數(shù)

代碼演示:

#5.將多個裝飾器應(yīng)用到同一個函數(shù)上
def wrapper1(fun):
    def inner1():
        print("1~~~~")
        fun()

    return inner1

def wrapper2(fun):
    def inner2():
        print("2~~~~")
        fun()

    return inner2

@wrapper1
@wrapper2
def show():
    print("hello")

show()

"""
1~~~~
2~~~~
hello
"""

#結(jié)論:多個裝飾器作用于同一個函數(shù)的時候刹悴,從第一個裝飾器開始行楞,從上往下依次執(zhí)行,但是土匀,原函數(shù)只會被執(zhí)行一次

四子房、函數(shù)遞歸【掌握】

1.概念

遞歸函數(shù):一個會調(diào)用自身的函數(shù)【在一個函數(shù)的內(nèi)部,自己調(diào)用自己】

遞歸調(diào)用

遞歸中包含了一種隱式的循環(huán)就轧,他會重復(fù)指定某段代碼【函數(shù)體】池颈,但這種循環(huán)不需要條件控制

使用遞歸解決問題思路:

? a.找到一個臨界條件【臨界值】

? b.找到相鄰兩次循環(huán)之間的關(guān)系

? c.一般情況下,會找到一個規(guī)律【公式】

2.使用

代碼演示:

#案例一
"""
               1 2 3 4 5 6 7  8  9 10  11.钓丰。躯砰。。
斐波那契數(shù)列:1,1,2,3,5,8,13,21,34,55,89.....

解決問題:報一個數(shù)携丁,輸出數(shù)列中對應(yīng)的數(shù)

規(guī)律:
a.第一個位置和第二個位置上數(shù)是固定的琢歇,都是1
b.第n個位置上的數(shù):第 n - 1 的數(shù)  +   第 n - 2 的數(shù)

r1 = func1(1)  ------>1
r2 = func1(2)  ------>1
r3 = fun1(3) ------>func1(1) + func1(2)----->1 + 1 = 2
r4 = fun1(4)------->fun1(3) + fun1(2) ----->func1(1) + func1(2) +  fun1(2) ---->1  + 1 + 1 = 3
r5 = fun1(5) ----->fun1(4) + fun1(3) ----->fun1(3) + fun1(2) + func1(1) + func1(2)--->func1(1) + func1(2) ++ fun1(2) + func1(1) + func1(2)--->5
.....
rn = fun1(n) ----->fun1(n- 1) + fun1(n - 2)
"""

def func1(num):
    #臨界值
    if num == 1 or num == 2:
        return 1
    else:
        #print("~~~~",num)
        result = func1(num- 1) + func1(num - 2)    #result = func1(1) + func1(2)  --->1 + 1 =2
        return result

print(func1(10))

#練習(xí);使用遞歸計算1~某個數(shù)之間的和
"""
add(1) = 1   :臨界值
add(2) = add(1) + 2
add(3) = add(2) + 3 ---->add(1) + 2 + 3 = 1 + 2 + 3
add(4) = add(3) + 4---->add(2) + 3 + 4 ---->add(1) + 2 + 3 + 4---->1 + 2 + 3 + 4
....
add(n) = add(n - 1) + n
"""
def add(num):

    """
    n = 1
    sum = 0
    while n <= 100:
        sum += n
        n += 1

    return sum

    sum1 = 0
    for i in range(1,num + 1):
        sum1 += i
    return  sum1
    """
    #使用遞歸實(shí)現(xiàn)
    if num == 1:
        return 1
    else:
        return add(num - 1) + num

print(add(100))

注意:以后在實(shí)際項目中盡量少用遞歸,如果隱式循環(huán)的次數(shù)太多梦鉴,會導(dǎo)致內(nèi)存泄漏【棧溢出】

優(yōu)點(diǎn):簡化代碼李茫,邏輯清晰

五、棧和隊列【了解】

用于存儲數(shù)據(jù)的線性表

棧:在表的一端進(jìn)行插入和刪除

隊列:在表的一端進(jìn)行插入肥橙,在表的另一端進(jìn)行數(shù)據(jù)的刪除

1.棧

Stack

開口向上的容器:先進(jìn)后出魄宏,后進(jìn)先出

代碼演示:

#list的底層維護(hù)了一個棧的線性表

myStack = []

#插入數(shù)據(jù)
#數(shù)據(jù)入棧【壓棿娣ぃ】
myStack.append(1)
print(myStack)
myStack.append(2)
print(myStack)
myStack.append(3)
print(myStack)
myStack.append(4)
print(myStack)   #[1,2,3,4]

#出棧
myStack.pop()
print(myStack)
myStack.pop()
print(myStack)
myStack.pop()
print(myStack)
myStack.pop()
print(myStack)

2.隊列

queue

水平放置的水管:先進(jìn)先出宠互,后進(jìn)后出

代碼演示:

import  collections   #數(shù)據(jù)結(jié)構(gòu)的集合

queue  = collections.deque([1,2,3,4])
print(queue)

#入隊【存儲數(shù)據(jù)】
queue.append(5)
print(queue)
queue.append(6)
print(queue)

#出隊【獲取數(shù)據(jù)】
queue.popleft()
print(queue)
queue.popleft()
print(queue)
queue.popleft()
print(queue)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市椭坚,隨后出現(xiàn)的幾起案子予跌,更是在濱河造成了極大的恐慌,老刑警劉巖善茎,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件券册,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)烁焙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門航邢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人骄蝇,你說我怎么就攤上這事膳殷。” “怎么了乞榨?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵秽之,是天一觀的道長当娱。 經(jīng)常有香客問我吃既,道長,這世上最難降的妖魔是什么跨细? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任鹦倚,我火速辦了婚禮,結(jié)果婚禮上冀惭,老公的妹妹穿的比我還像新娘震叙。我一直安慰自己,他們只是感情好散休,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布媒楼。 她就那樣靜靜地躺著,像睡著了一般戚丸。 火紅的嫁衣襯著肌膚如雪划址。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天限府,我揣著相機(jī)與錄音夺颤,去河邊找鬼。 笑死胁勺,一個胖子當(dāng)著我的面吹牛世澜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播署穗,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼寥裂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了案疲?” 一聲冷哼從身側(cè)響起抚恒,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎络拌,沒想到半個月后俭驮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年混萝,在試婚紗的時候發(fā)現(xiàn)自己被綠了遗遵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡逸嘀,死狀恐怖车要,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情崭倘,我是刑警寧澤翼岁,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站司光,受9級特大地震影響琅坡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜残家,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一榆俺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧坞淮,春花似錦茴晋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至啡直,卻和暖如春烁涌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背付枫。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工烹玉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阐滩。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓二打,卻偏偏與公主長得像,于是被迫代替她去往敵國和親掂榔。 傳聞我的和親對象是個殘疾皇子继效,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容