1. 程式人生 > >孤荷凌寒自學python第十六天python的迭代物件

孤荷凌寒自學python第十六天python的迭代物件

孤荷凌寒自學python第十六天python的迭代物件

 

(完整學習過程螢幕記錄視訊地址在文末,手寫筆記在文末)

迭代也就是迴圈。

python中的迭代物件有相關的如下幾個術語:

A容器 contrainer

       序列/集合/字典等都是容器,我的理解是因為它們都容納了很多的元素在其中,每個元素都是別的物件,所以稱他們為容器非常貼切。

B 可迭代物件 iterable

       大部分容器都是可迭代物件(iterable)

       可迭代物件的意思 是,這個物件本身可以提供有限數量的內部元素供迴圈語句遍歷,因此多數容器都符合這個條件。

C 迭代器 iterater

       可迭代物件可以轉換為 迭代器

       使用函式

       迭代器物件=iter(可迭代物件)

       就可將一個可迭代物件轉換為一個 迭代器。

      迭代器 可以直接自動地 逐一將自己變數名所指向 的 記憶體中的地址 中的元素 一個一個地 根據迴圈語句的 需要 逐次(每次提交下一個元素 指向記憶體的起始地址給迴圈體)

提供。

       部分迭代器 甚至可以將有限的元素集合模擬成無限的數量。迴圈語句獲取時將發現似乎其中的元素永遠都取之不盡。這個目前我沒有深入研究。

       用print語句嘗試輸出迭代器物件時,會發現,打印出的它被表示成了記憶體地址的形式。

 

D 生成器——一種特殊的迭代器

       generator

       yield

       關於生成器,目前沒有深入學習。

 

一、判斷 一個 物件 是不是 可迭代物件,是不是 迭代器 的方法

需要引用模組(庫),然後再使用相關函式

用到的庫是:

collections.py

引用宣告:

from collections import Iterable

from collections import Iterator

然後使用全域性函式

isinstance來判斷型別

1 判斷 一個物件 是否是一個可迭代物件

isinstance(要判斷的物件,Iterable)

函式返回布林值。

2 判斷 一個物件 是否是一個迭代器

isinstance(要判斷的物件,Iterator)

函式返回布林值。

 

二、其它可以自動產生迭代器的常用函式

iter函式可以將 可迭代物件轉換成 迭代器

除此之外,以下函式 也可以生成 迭代器:

1 range()函式

range函式用於生成指定的整數序列列表對應的迭代器

格式:

新的迭代器物件=range(起始整數(包含此數),結束整數(不包含此數),步長)

測試:

>>> itrA=range(1,20,2)

>>> print(itrA)

range(1, 20, 2)

>>> for a in itrA:  #itrA作為一個迭代器,可以向迴圈語句中的變數a逐一提供其中的元素。

       print(a)

 

1

3

5

7

9

11

13

15

17

19

 

2 enumerate()函式

此函式會將一個普通序列轉換成由元素本身在序列中的index數值與元素物件本身一一對應的一個個元組對組成的複合序列物件對應的 迭代器

格式:

新的迭代器=enumerate(序列物件)

測試:

>>> lstA=list('大家好,我是孤荷凌寒')

>>> itrB=enumerate(lstA)

>>> print(itrB)

#用print語句輸出迭代器時,會發現打印出的它被表示成了記憶體地址的形式。

<enumerate object at 0x000001C940156EA0>

>>> for index,obj in itrB:  #迭代器itrB每次向迴圈語句提供同一元素的兩個物件

       print('當前元素index:',index,'值:',obj)

 

當前元素index: 0 值: 大

當前元素index: 1 值: 家

當前元素index: 2 值: 好

當前元素index: 3 值: ,

當前元素index: 4 值: 我

當前元素index: 5 值: 是

當前元素index: 6 值: 孤

當前元素index: 7 值: 荷

當前元素index: 8 值: 凌

當前元素index: 9 值: 寒

 

3 sorted()函式

對序列進行排序。

格式:

sorted(序列物件,key=排序關鍵字函式,排序方向的布林值)

排序關鍵字函式,是我的理解並備註。

此引數是關鍵字引數,必須以

key=函式名

key=適時定義的匿名函式

的方式來進行傳遞。

而我的理解是,這個函式其實只是指定了以序列中的元素的哪個關鍵字(或部分)來進行排序,並定義具體的排序規則,可以存在多種複雜的規則。

排序方向的布林值,只能傳遞布林值True或False中的其中一個,如果傳入True,表示逆序排序;如果傳入False,表示正序排序。

特別注意:

我發現此函式與今天所學的其它函式都不同的地方在於,它並不是 返回了一個迭代器物件,而是返回的真正的序列物件。原序列的內容沒有改變。

測試:

lstA=[('john','A',15),('jone','B',12),('dave','B',10)]

print(sorted(lstA,key=lambda x:x[2])) #這兒的排序函式是實時定義的匿名函式,只指明瞭按列表中元素——是元組物件的index為2的元素的值進行排序。

 

執行結果:

[('dave', 'B', 10), ('jone', 'B', 12), ('john', 'A', 15)]

從執行結果中可以看出——

此列表,共有三個元素,每個元素都是一個元組;

每個元組都有三個元素,index值分別為0,1,2;

而實時定義的排序關鍵字函式指明瞭x:x[2],按元組物件的index為2的元素的大小排序。

於是結果是正確的排好的序,10<12<15

現在我們對排序函式進行修改:

lstA=[('john','A',15),('jone','B',12),('dave','B',10)]

print(sorted(lstA,key=lambda x:x[0])) #這兒的排序函式是實時定義的匿名函式,只指明瞭按列表中元素——是元組物件的index為0的元素的值進行排序。

 

執行結果:

[('dave', 'B', 10), ('john', 'A', 15), ('jone', 'B', 12)]

 

4 reversed() 函式

此函式反轉一個序列中元素的先後順序。

格式:

新的迭代器物件=reversed(序列物件)

測試:

strA='孤荷凌寒參加工作後,每天在工作之外的空閒時間只能看著窗外的群山發呆,小山村沒多少人,雖然自己也在農村長大,但孤荷凌寒並不玩牌,也性格內向。'

itrA=reversed(strA)

print(itrA) #直接列印 迭代器,只能顯示 記憶體地址

lstA=list(itrA)  #只能轉換成list才能顯示,不能直接還原成字串了

print(lstA)

運算結果:

<reversed object at 0x000001DF1EFE4C88>

['。', '向', '內', '格', '性', '也', ',', '牌', '玩', '不', '並', '寒', '凌', '荷', '孤', '但', ',', '大', '長', '村', '農', '在',

'也', '己', '自', '然', '雖', ',', '人', '少', '多', '沒', '村', '山', '小', ',', '呆', '發', '山', '群', '的', '外', '窗', '著', '看', '能', '只', '間', '時', '閒', '空', '的', '外', '之', '作', '工', '在', '天', '每', ',', '後', '作', '工', '加', '參', '寒', '

凌', '荷', '孤']

 

5 filter() 函式

篩選一個序列,留下 序列中符合篩選條件的元素,返回新的迭代器:

新的迭代器=filter(篩選函式,序列)

篩選函式將有一個引數,對應於序列中的每一個元素。

且篩選函式的返回物件只能是布林物件即:True  或者 False

在filter函式執行時,序列中的每一個元素都會被作為實參傳遞進篩選函式中進行運算,當序列中的一個元素傳遞進篩選函式後,如果篩選函式的運算結果是:True,則此元素會被認為符合篩選條件而通過篩選,被存放入新的迭代器物件中;如果篩選函式運算的結果是False,則此元素會被認為不符合篩選條件,就被忽略掉。

測試:

strA='孤荷凌寒參加工作後,每天在工作之外的空閒時間只能看著窗外的群山發呆,小山村沒多少人,雖然自己也在農村長大,但孤荷凌寒並不玩牌,也性格內向。'

def shaixuan(yuansu):

    strKey='孤荷凌寒'

    if yuansu==',':

        return True

    elif yuansu in strKey:

        return True

    else:

        return False

 

itrA=filter(shaixuan,strA)

print(itrA)

lstA=list(itrA)

print(lstA)

運算結果 :

<filter object at 0x000002457AB54C88>

['孤', '荷', '凌', '寒', ',', ',', ',', ',', '孤', '荷', '凌', '寒', ',']

 

6 map()函式

將指定的一個或多個序列的每個元素都由作為指定的同一個函式的實參,然後由函式進行運算,並返回結果,然後將所有結果組合成一個新的迭代器物件返回。

格式:

map(執行函式名 ,序列 [,序列2] [,序列3] [……])

執行函式名是指要對序列的每個元素進行運算而事先已經定義好的函式的函式名。

此函式要求至少要有一個形式引數,以便序列的每個元素都可以作為實參而傳遞進入函式體內進行運算。

此函式在對序列的每個元素進行運算後都必須返回一個物件。

map()函式與filter()函式的不同之處在於,map()函式可以一次接受傳入多個序列。

傳入n個序列則意味著map()函式的第一個形參——執行函式——必須要有n個形式引數,以便接收n個序列的各自的每個元素參與執行函式內部的運算。

測試:

strA='讀書是當時孤荷凌寒與外部世界溝通的唯一通道。'

strB='孤荷凌寒利用一切可以利用的休息時間學習。'

strC='當孤荷凌寒知道了世界上還有“電腦”這樣的神奇的東西存在之後'

strD='孤荷凌寒準備自己學習英語,為的是有一天能夠學習電腦。'

def function(yuansu):

    strKey='孤荷凌寒'

    if yuansu==',':

        return '逗號'

    elif yuansu in strKey:

        return yuansu

    else:

        return '0'

 

itrA=map(function,strA)

print(itrA)

lstA=list(itrA)

print(lstA)

運算結果:

<map object at 0x000001D3E0FB4D30>

['0', '0', '0', '0', '0', '孤', '荷', '凌', '寒', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']

傳入多個序列的測試:

strA='孤荷凌寒讀書是當時與外部世界溝通的唯一通道。'

strB='孤荷凌寒利用一切可以利用的休息時間學習。'

strC='當孤荷凌寒知道了世界上還有“電腦”這樣的神奇的東西存在之後'

strD='孤荷凌寒準備自己學習英語,為的是有一天能夠學習電腦。'

def function(yuansu,ys2,ys3,ys4):

    strKey='孤荷凌寒'

    if ((yuansu in strKey) and (ys2 in strKey) and (ys3 in strKey) and (ys4 in strKey)):

        return '命中'

    else:

        return '0'

 

itrA=map(function,strA,strB,strC,strD)

print(itrA)

lstA=list(itrA)

print(lstA)

執行結果:

<map object at 0x00000227EFFE7BE0>

['0', '命中', '命中', '命中', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']

 

7 reduce()

from functools import reduce

newobj=reduce(func,序列[,數值常量][……])

此函式的用法,我的初步理解是:

將傳入的序列用函式 func 進行計算

定義的func函式有幾個形參就要有幾個序列和常量傳入

此函式沒有完全弄清楚,測試如下:

from functools import reduce

def func(var,var2):

    return var + var2

lstA=[1,2,3,4]

lstB=[4,3,2,1]

intA=reduce(func,lstA,10)

print(intA)

運算結果:

20

 

——————————

今天整理的學習筆記完成,最後例行說明下我的自學思路:

根據過去多年我自學各種程式語言的經歷,認為只有真正體驗式,解決實際問題式的學習才會有真正的效果,即讓學習實際發生。在2004年的時候我開始在一個鄉村小學自學電腦 並學習vb6程式語言,沒有學習同伴,也沒有高師在上,甚至電腦都是孤島(鄉村那時還沒有網路),有的只是一本舊書,在痛苦的自學摸索中,我找到適應自己零基礎的學習方法:首先是每讀書的一小節就作相應的手寫筆記,第二步就是上機測試每一個筆記內容是否實現,其中會發現書中講的其實有出入或錯誤,第三步就是在上機測試之後,將筆記改為電子版,形成最終的修訂好的正確無誤的學習筆記 。

通過反覆嘗試錯誤,在那個沒有分享與交流的黑暗時期我摸黑學會了VB6,爾後接觸了其它語言,也曾聽過付費視訊課程,結果發現也許自己學歷果然太低,就算是零基礎的入門課程,其實也難以跟上進度,講師的教學多數出現對初學者的實際情況並不瞭解的情況,況且學習者的個體也存在差異呢?當然更可怕的是收費課程的價格往往是自己難以承受的。

於是我的所有程式設計學習都改為了自學,繼續自己的三步學習筆記法的學習之路。

當然自學的最大問題是會走那麼多的彎路,沒有導師直接輸入式的教學來得直接,好在網路給我們帶來無限搜尋的機會,大家在網路上的學習日誌帶給我們共享交流的機會,而QQ群等交流平臺、網路社群的成立,我們可以一起自學,互相批評交流,也可以獲得更有效,更自主的自學成果。

於是我以人生已過半的年齡,決定繼續我的程式設計自學之路,開始學習python,只希望與大家共同交流,一個人的獨行是可怕的,只有一群人的共同前進才是有希望的。

誠摯期待您的交流分享批評指點!歡迎聯絡我加入從零開始的自學聯盟。

這個時代網際網路成為了一種基礎設施的存在,於是本來在孤獨學習之路上的我們變得不再孤獨,因為網路就是一個新的客廳,我們時刻都可以進行沙龍活動。

非常樂意能與大家一起交流自己自學心得和發現,更希望大家能夠對我學習過程中的錯誤給予指點——是的,這樣我就能有許多免費的高師了——這也是分享時代,社群時代帶來的好福利,我相信大家會的,是吧!

 

根據完全共享的精神,開源互助的理念,我的個人自學錄製過程是全部按4K高清視訊錄製的,從手寫筆記到驗證手寫筆記的上機操作過程全程錄製,但因為4K高清檔案太大均超過5G以上,所以無法上傳至網路,如有需要可聯絡我QQ578652607對傳,樂意分享。上傳分享到百度網盤的只是壓縮後的720P的視訊。

 

我的學習過程錄影百度盤地址分享如下:(清晰度:1280x720)

連結:https://pan.baidu.com/s/18DrDIY1HCirswLexdS9PDw  密碼:liz8

 

Bilibili:

https://www.bilibili.com/video/av35841103/

 

喜馬拉雅語音筆記:

https://www.ximalaya.com/keji/19103006/138930894