日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

3.Python迭代器(函數(shù)名的應(yīng)用,新版格式化輸出)

系統(tǒng) 1803 0

1. 函數(shù)名的運用

? 你們說一下,按照你們的理解,函數(shù)名是什么?

? 函數(shù)名的定義和變量的定義幾乎一致,在變量的角度,函數(shù)名其實就是一個變量,具有變量的功能:可以賦值;但是作為函數(shù)名他也有特殊的功能就是加上()就會執(zhí)行對應(yīng)的函數(shù),所以我們可以把函數(shù)名當(dāng)做一個特殊的變量,那么接下來,我們就來研究一下這個特殊的變量。

1.1 函數(shù)的內(nèi)存地址

          
            def func():        
    print("呵呵")
print(func)結(jié)果: 
            
          
        

? 通過上面代碼可以我們知道,函數(shù)名指向的是這個函數(shù)的內(nèi)存地址,其實深一步理解可得知,與其說函數(shù)名()可以執(zhí)行這個函數(shù),不如說是函數(shù)的內(nèi)存地址()才是執(zhí)行這個函數(shù)的關(guān)鍵,就好比:

          
            a = 1
b = 2
c = a + b
print(c)  # 3
          
        

a + b 并不是變量的相加,而是 兩個變量指向的int對象的相加。

1.2 函數(shù)名可以賦值給其他變量

如果你理解了第一條,那么第二條就更容易的理解了:

          
            def func():        
    print("呵呵")    
print(func) 
a = func  # 把函數(shù)當(dāng)成一個變量賦值給另一個變量
a() # 函數(shù)調(diào)用 func()
          
        

通過變量的賦值,變量a,和變量func都指向的這個函數(shù)的內(nèi)存地址,那么a() 當(dāng)然可以執(zhí)行這個函數(shù)了。

1.3 函數(shù)名可以當(dāng)做容器類的元素

其實這個也不難理解,函數(shù)名就是一個變量,我的變量是可以當(dāng)做容器類類型的元素的:

          
            a = 1
b = 'alex'
c = '武sir'
l1 = [a, b, c]
for i in l1:
    print(i)
'''
# 結(jié)果:
1
alex
武sir
'''
          
        

那么函數(shù)名也是可以的:

          
            def func1():
    print("in func1: 嘻嘻")
def func2():
    print("in func2: 哈哈")
def func3():
    print("in func3: 咯咯")
def func4():
    print("in func4: 吱吱")
lst = [func1, func2, func3, func4]
for i in lst:
    i()
          
        

1.4 函數(shù)名可以當(dāng)做函數(shù)的參數(shù)

變量可以做的,函數(shù)名都可以做到。

          
            def func1():
    print('in func1')

def func2(f):
    print('in func2')
    f()

func2(func1)
          
        

1.5 函數(shù)名可以作為函數(shù)的返回值

          
            def func1():
    print('in func1')

def func2(f):
    print('in func2')
    return f

ret = func2(func1)
ret()  # ret, f, func1 都是指向的func1這個函數(shù)的內(nèi)存地址
          
        

小結(jié) :函數(shù)名是一個特殊的變量,他除了具有變量的功能,還有最主要一個特點就是加上() 就執(zhí)行,其實他還有一個學(xué)名叫 第一類對象

2 Python新特性:f-strings格式化輸出

? f-strings 是python3.6開始加入標準庫的格式化輸出新的寫法,這個格式化輸出比之前的%s 或者 format 效率高并且更加簡化,非常的好用,相信我,你們學(xué)完這個之后,以后再用格式化輸出這就是你們唯一的選擇。

2.1 簡單舉例

? 他的結(jié)構(gòu)就是F(f)+ str的形式,在字符串中想替換的位置用{}展位,與format類似,但是用在字符串后面寫入替換的內(nèi)容,而他可以直接識別。碉堡了。

          
            name = '太白金星'
age = 18
sex = '男'
msg = F'姓名:{name},性別:{age},年齡:{sex}'  # 大寫字母也可以
msg = f'姓名:{name},性別:{age},年齡:{sex}'  
print(msg)
'''
輸出結(jié)果:
姓名:太白金星,性別:18,年齡:男
'''
          
        

2.2 任意表達式

他可以加任意的表達式,非常方便:

          
            print(f'{3*21}')  # 63

name = 'barry'
print(f"全部大寫:{name.upper()}")  # 全部大寫:BARRY

# 字典也可以
teacher = {'name': '太白金星', 'age': 18}
msg = f"The teacher is {teacher['name']}, aged {teacher['age']}"
print(msg)  # The comedian is 太白金星, aged 18

# 列表也行
l1 = ['太白金星', 18]
msg = f'姓名:{l1[0]},年齡:{l1[1]}.'
print(msg)  # 姓名:太白金星,年齡:18.
          
        

2.3 也可以插入表達式

可以用函數(shù)完成相應(yīng)的功能,然后將返回值返回到字符串相應(yīng)的位置

          
            def sum_a_b(a,b):
    return a + b
a = 1
b = 2
print('求和的結(jié)果為' + f'{sum_a_b(a,b)}')
          
        

2.4 多行f

          
            name = 'barry'
age = 18
ajd = 'handsome'

# speaker = f'''Hi {name}.
# You are {age} years old.
# You are a {ajd} guy!'''

speaker = f'Hi {name}.'\
          f'You are {age} years old.'\
          f'You are a {ajd} guy!'
print(speaker)
          
        

2.5 其他細節(jié)

這里有一些注意的細節(jié),了解一下就行。

          
            print(f"{{73}}")  # {73}
print(f"{{{73}}}")  # {73}
print(f"{{{{73}}}}")  # {{73}}
m = 21
# ! , : { } ;這些標點不能出現(xiàn)在{} 這里面。
# print(f'{;12}')  # 報錯
# 所以使用lambda 表達式會出現(xiàn)一些問題。
# 解決方式:可將lambda嵌套在圓括號里面解決此問題。
x = 5
print(f'{(lambda x: x*2) (x)}')  # 10
          
        

總結(jié) :f-string的格式化輸出更加簡潔,方便,易讀。而且他的處理速度對之前的%s 或者format 有了較高的提升,所以以后盡量使用此種格式化輸出。

3. 迭代器

3.1 可迭代對象

1) 可迭代對象定義

? 對于迭代器來說,我們更熟悉的應(yīng)該是可迭代對象,之前無論是源碼還是講課中或多或少我們提到過可迭代對象這個詞。之前為了便于大家理解可迭代對象,可能解釋的不是很正確,所以今天我們正式的聊一聊什么是可迭代對象。從字面意思來說,我們先對其進行拆解:什么是對象?Python中一切皆對象,之前我們講過的一個變量,一個列表,一個字符串,文件句柄,函數(shù)名等等都可稱作一個對象,其實一個對象就是一個實例,就是一個實實在在的東西。那么什么叫迭代?其實我們在日常生活中經(jīng)常遇到迭代這個詞兒,更新迭代等等,迭代就是一個重復(fù)的過程,但是不能是單純的重復(fù)(如果只是單純的重復(fù)那么他與循環(huán)沒有什么區(qū)別)每次重復(fù)都是基于上一次的結(jié)果而來。比如你爹生你,你生你爹,哦不對,你生你兒子,你兒子生你孫子等等,每一代都是不一樣的;還有你使用過得app,微信,抖音等,隔一段時間就會基于上一次做一些更新,那么這就是迭代。可迭代對象從字面意思來說就是一個可以重復(fù)取值的實實在在的東西。

? 那么剛才我們是從字面意思分析的什么是可迭代對象,到目前為止我們接觸到的可迭代對象有哪些呢?

? str list tuple dic set range 文件句柄等,那么int,bool這些為什么不能稱為可迭代對象呢?雖然在字面意思這些看著不符合,但是我們要有一定的判斷標準或者規(guī)則去判斷該對象是不是可迭代對象。

? **在python中,但凡內(nèi)部含有__iter__方法的對象,都是可迭代對象**。

2) 查看對象內(nèi)部方法

? 該對象內(nèi)部含有什么方法除了看源碼還有什么其他的解決方式么?當(dāng)然有了, 可以通過dir() 去判斷一個對象具有什么方法

          
            s1 = 'alex'
print(dir(s1))
          
        

dir()會返回一個列表,這個列表中含有該對象的以字符串的形式所有方法名。這樣我們就可以判斷python中的一個對象是不是可迭代對象了:

          
            s1 = 'alex'
i = 100
print('__iter__' in dir(i))  # False
print('__iter__' in dir(s1))  # True
          
        

3)小結(jié)

? 從字面意思來說:可迭代對象就是一個可以重復(fù)取值的實實在在的東西。

? 從專業(yè)角度來說:但凡內(nèi)部含有__iter__方法的對象,都是可迭代對象。

? 可迭代對象可以通過判斷該對象是否有’ iter ’方法來判斷。

? 可迭代對象的優(yōu)點:

? 可以直觀的查看里面的數(shù)據(jù)。

? 可迭代對象的缺點:

? \1. 占用內(nèi)存。

? \2. 可迭代對象不能迭代取值(除去索引,key以外)。

? 那么這個缺點有人就提出質(zhì)疑了,即使拋去索引,key以外,這些我可以通過for循環(huán)進行取值呀!對,他們都可以通過for循環(huán)進行取值,其實for循環(huán)在底層做了一個小小的轉(zhuǎn)化,就是先將可迭代對象轉(zhuǎn)化成迭代器,然后在進行取值的。那么接下來,我們就看看迭代器是個什么鬼。

3.2 迭代器

1) 迭代器的定義

? 從字面意思來說迭代器,是一個可以迭代取值的工具,器:在這里當(dāng)做工具比較合適。

? 從專業(yè)角度來說:迭代器是這樣的對象:實現(xiàn)了無參數(shù)的__next__方法,返回序列中的下一個元素,如果沒有元素了,那么拋出StopIteration異常.python中的迭代器還實現(xiàn)了__iter__方法,因此迭代器也可以迭代。 出自《流暢的python》

? 那么對于上面的解釋有一些超前,和難以理解,不用過于糾結(jié),我們簡單來說: 在python中,內(nèi)部含有' Iter '方法并且含有' next '方法的對象就是迭代器。

2) 如何判斷該對象是否是迭代器

? ok,那么我們有了這個定義,我們就可以判斷一些對象是不是迭代器或者可迭代對象了了,請判斷這些對象:str list tuple dict set range 文件句柄 哪個是迭代器,哪個是可迭代對象:

          
            o1 = 'alex'
o2 = [1, 2, 3]
o3 = (1, 2, 3)
o4 = {'name': '太白','age': 18}
o5 = {1, 2, 3}
f = open('file',encoding='utf-8', mode='w')
print('__iter__' in dir(o1))  # True
print('__iter__' in dir(o2))  # True
print('__iter__' in dir(o3))  # True
print('__iter__' in dir(o4))  # True
print('__iter__' in dir(o5))  # True
print('__iter__' in dir(f))  # True
# hsagn
print('__next__' in dir(o1))  # False
print('__next__' in dir(o2))  # False
print('__next__' in dir(o3))  # False
print('__next__' in dir(o4))  # False
print('__next__' in dir(o5))  # False
print('__next__' in dir(f))  # True
f.close()
          
        

通過以上代碼可以驗證,之前我們學(xué)過的這些對象,只有文件句柄是迭代器,剩下的那些數(shù)據(jù)類型都是可迭代對象。

3) 可迭代對象如何轉(zhuǎn)化成迭代器:

          
            l1 = [1, 2, 3, 4, 5, 6]
obj = l1.__iter__() 
# 或者 iter(l1)print(obj) 
# 
            
          
        

4) 迭代器取值:

? 可迭代對象是不可以一直迭代取值的(除去用索引,切片以及Key),但是轉(zhuǎn)化成迭代器就可以了,迭代器是利用__next__()進行取值:

          
            l1 = [1, 2, 3,]
obj = l1.__iter__()  # 或者 iter(l1)
# print(obj)  # 
            
              
ret = obj.__next__()
print(ret)
ret = obj.__next__()
print(ret)
ret = obj.__next__()
print(ret)
ret = obj.__next__()  # StopIteration
print(ret)
# 迭代器利用next取值:一個next取對應(yīng)的一個值,如果迭代器里面的值取完了,還要next,
# 那么就報StopIteration的錯誤。
            
          
        

5) while模擬for的內(nèi)部循環(huán)機制:

? 剛才我們提到了,for循環(huán)的循環(huán)對象一定要是可迭代對象,但是這不意味著可迭代對象就可以取值,因為for循環(huán)的內(nèi)部機制是:將可迭代對象轉(zhuǎn)換成迭代器,然后利用next進行取值,最后利用異常處理處理StopIteration拋出的異常。

          
            l1 = [1, 2, 3, 4, 5, 6]
# 1 將可迭代對象轉(zhuǎn)化成迭代器
obj = iter(l1)
# 2,利用while循環(huán),next進行取值
while 1:
    # 3,利用異常處理終止循環(huán)
    try:
        print(next(obj))
    except StopIteration:
        break
          
        

6)小結(jié):

? 從字面意思來說:迭代器就是可以迭代取值的工具。

? 從專業(yè)角度來說:在python中,內(nèi)部含有' Iter '方法并且含有' next '方法的對象就是迭代器。

? 迭代器的優(yōu)點:

? 節(jié)省內(nèi)存。
? 迭代器在內(nèi)存中相當(dāng)于只占一個數(shù)據(jù)的空間:因為每次取值都上一條數(shù)據(jù)會在內(nèi)存釋放,加載當(dāng)前的此條數(shù)據(jù)。

? 惰性機制。
? next一次,取一個值,絕不過多取值。?

? 有一個迭代器模式可以很好的解釋上面這兩條:迭代是數(shù)據(jù)處理的基石。掃描內(nèi)存中放不下的數(shù)據(jù)集時,我們要找到一種惰性獲取數(shù)據(jù)項的方式,即按需一次獲取一個數(shù)據(jù)項。這就是迭代器模式。

? 迭代器的缺點:

? 不能直觀的查看里面的數(shù)據(jù)。

? 取值時不走回頭路,只能一直向下取值。

          
            l1 = [1, 2, 3, 4, 5, 6]
obj = iter(l1)

for i in range(2):
    print(next(obj))

for i in range(2):
    print(next(obj))
          
        

3.3 可迭代對象與迭代器對比

? 我們今天比較深入的了解了可迭代對象與迭代器,接下來我們說一下這兩者之間比較與應(yīng)用:

? 可迭代對象:

? 是一個私有的方法比較多,操作靈活(比如列表,字典的增刪改查,字符串的常用操作方法等),比較直觀,但是占用內(nèi)存,而且不能直接通過循環(huán)迭代取值的這么一個數(shù)據(jù)集。

? 應(yīng)用 :當(dāng)你側(cè)重于對于數(shù)據(jù)可以靈活處理,并且內(nèi)存空間足夠,將數(shù)據(jù)集設(shè)置為可迭代對象是明確的選擇。

? 迭代器:

? 是一個非常節(jié)省內(nèi)存,可以記錄取值位置,可以直接通過循環(huán)+next方法取值,但是不直觀,操作方法比較單一的數(shù)據(jù)集。

? 應(yīng)用 :當(dāng)你的數(shù)據(jù)量過大,大到足以撐爆你的內(nèi)存或者你以節(jié)省內(nèi)存為首選因素時,將數(shù)據(jù)集設(shè)置為迭代器是一個不錯的選擇。(可參考為什么python把文件句柄設(shè)置成迭代器)。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 永和县| 铜陵市| 吕梁市| 南通市| 天门市| 得荣县| 同仁县| 水城县| 永寿县| 湛江市| 固镇县| 蚌埠市| 莎车县| 璧山县| 阿拉善右旗| 新沂市| 澳门| 怀宁县| 南开区| 旬阳县| 沅江市| 闻喜县| 茶陵县| 德钦县| 柏乡县| 常德市| 沅江市| 中牟县| 泗水县| 涟源市| 民县| 金寨县| 霞浦县| 杨浦区| 辽宁省| 运城市| 临潭县| 鱼台县| 霍邱县| 永昌县| 新昌县|