帥小夥,開始學python,大數據時代到來啦,我也要跟進

今天推薦的python書籍是《python cookbook》這本書適合看完python基礎語法後的同學,可以作為進階複習的小冊子,本菜雞推薦給大家,鏈接文章末尾自取。

本菜雞立志要啃下這本書進階書,希望和大家一起學習交流。


第一章 1.1解壓多個序列賦值給多個變量

先貼上源碼show me your code

現在有一個包含 N 個元素的元組或者是序列,怎樣將它裡面的值解壓後同時賦值給 N 個變量?


意思就是將一個序列(這裡可以認為是一個可迭代的對象列表元組集合字符串等)的元素分別同時給多個變量賦值。


這個過程就是解壓,將元素一個個掏出來並分別賦值給不同的變量,我們想看那個,想用那個,就可以直接用變量來替代。就不用用索引去查找了。


我沒有照抄書中的源碼,而是自己舉例子並模仿學習,我不敢否認照抄書中源碼沒有效果,但是想要達到舉一反三的效果,最好還是修改下書中的代碼,不能太懶,對吧。


<code> 1#解壓可迭代數值,同時解壓到同等數量的變量
2mylist = ["王剛",26,176,{"data":["河南","鄭州",'人力資源','總監']}]
3name,age,height,info = mylist
4print("{:-^30}".format("我是分割線"))
5print("""name:{0:^10}
6age:{1:^12}
7height:{2:^8}
8祖籍:{3:^11}
9居住城市:{4:^4}
10崗位:{5:^12}
11職位:{6:^10}""".format(name,age,height,info["data"][0],info["data"][1],info["data"][2],info["data"][3]))
12print("{:-^30}".format("我是分割線"))
/<code>

  • 這段代碼中可能格式化函數有些同學語法記不太清,這時候就可以去發揮搜索的能力去搜索format()函數語法,這些都不是難事。
  • 這段代碼就是將mylist列表的每個元素,分別賦值給四個變量,name是字符串,age和height是整型,info是字典。
  • print打印多行字符串,應該將字符串用三引號括起來。
  • 第11行代碼中format()內部參數是用變量名和字典鍵值對加上列表索引定位的值,至於{}內語法,無非就是字符串寬度和對其方式。語法可自行查閱,不要偷懶。


當然如果你只想提取部分數據,可以將過濾掉的數據用下劃線_代替變量名,其實下劃線也是一種變量名,還記得變量名命名的方式嗎,對,就是數字字母下劃線且不能數字開頭,所以可以用下劃線開頭,這裡使用下劃線表示統統不要,哈哈。


<code>1#不想要的數據可以用_代替,就不用使用變量名
2data =["tao",24,'河北','保定']
3name,_,province,_ = data
4print(name,province)
5print(_) #_也可以當變量名,這裡只不過是矇蔽大家雙眼,讓大家只關注重要的變量
/<code>


劃重點:請記住變量名和下劃線線_的數量(有下劃線的情況下)要與後面的序列或者列表等類型的長度對應,也可以理解為前面變量數和後面的元素個數對應。否則,解壓的時候會產生異常。可以嘗試看看異常是什麼。


實際上,這種解壓賦值可以用在任何可迭代對象上面,而不僅僅是列表或者元組。包括字符串,文件對象,迭代器和生成器。那我們就嘗試下迭代器是否可以解壓賦值。


說到迭代器,突然心頭一緊,好像忘記啥是迭代器,或者概念不清出來,不用怕,我們會搜索。複習一下不就完了。推薦廖雪峰教程迭代器的講解:https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640


看完是不是還是有點迷糊,我來總結一下:

  • 凡是生成器,必為迭代器;
  • 生成器分兩種:一種使用圓括號括起來(x for x in range(5))這種,別輕視圓括號,中括號括起來就不行[x for x in range(5)],中括號括起來的仍然是列表,圓括號括起來是生成器,不信可以用type()打印一下,查看打印結果;另外一種是含有yield的函數,yield是一個個往外蹦數據,和return有點類似都是返回一個結果,但是還是有區別的,具體這裡不詳細談了,自己去搜吧,學完基礎這個應該過關了。忘記了也不要緊,重新看一下就好了。

用例子來驗證我們的想法。_collections_abc這個模塊不用管,就是為驗證經過iter()函數轉換後的類型是不是迭代器,很顯然是前面的想法正確的。學好編程,時刻懷有驗證懷疑的心態。


<code> 1from _collections_abc import Iterator
2box = [12,"python",[1,2,3]] #列表本身可迭代,但是不是迭代器,用iter()方法變成迭代器
3print("列表box是不是迭代器:",isinstance(box,Iterator))
4new_iterator = iter(box) #變成迭代器
5print("new_iterator是不是迭代器:",isinstance(new_iterator,Iterator))
6num,language,inbox = new_iterator
7print("""num:{}
8language:{}
9inbox:{}
10""".format(num,language,inbox))
/<code>


到這裡,可能有人疑惑為什麼要把列表變成迭代器,然後再解壓,覺得這是多次一舉,恭喜你,懂得懷疑是學習的動力,這裡的初衷:儘管我們知道列表可以直接解壓,但是我們不知道迭代器是否能解壓。所以我們嘗試了一下。答案是可以的。


接下來,我還想嘗試下生成器中的元素是否可以被解壓到不同的變量中。

  • 首先創建生成器,這裡我就創建一個yield類型的函數迭代器,可以用next()方法調用返回值。
  • 代碼如下:
<code> 1#創建生成器函數
2from _collections_abc import Iterator
3def func():
4    print("提取第一個字母")
5    yield  "a"
6    print("提取第二個字母")
7    yield "b"
8    print("提取第三個字母")
9    yield "c"
10# print(next(func()))
11# print(next(func()))
12# print(next(func()))
13#上面這幾行代買,雖然打印了三次,其實只調用的了一次,所以每次只返回第一個yield後面值
14
15myfunc = func() #必須調用賦值,對函數進行next()才能不斷生成值
16print(next(myfunc))
17print(next(myfunc))
18print(next(myfunc))
19
20print(isinstance(myfunc,Iterator)) #是迭代器
21print(type(myfunc)) #<class> 是生成器
22#同時是生成器和迭代器並不衝突,因為生成器必然是迭代器
23
24#開始解壓
25fist_letter,second_letter,third_letter = func()
26print(fist_letter,second_letter,third_letter)
27#解壓調用的函數也可以,但要把16行-18行三行代碼註釋掉,因為,前面三次next()調用已經把myfunc的返回值返回完了,只剩一個Stopration異常拋出

28fist_letter,second_letter,third_letter = myfunc
29print(fist_letter,second_letter,third_letter)
/<class>/<code>


不要停,繼續肝


接下來解壓文件對象,這個比較簡單,書中的意思我是如下理解,好像有點,多次一舉,創建文件對象然後添加到列表,然後又從列表取出,這明顯就是一個逆過程,不用看也是可以的,好吧,我就是嘗試一下, 看看是否可以解壓文件對象,我理解的題目可能不太清楚,作者難道是用os模塊查看某個路徑下的文件名列表,那也不是文件對象啊,文件名完全可以用for循環路徑,然後打開文件,到頭來還是將文件添加到列表,進行解壓解包。。可能這道題目有問題。不深究了。說的有囉嗦。


<code> 1#創建多個文件,保存到列表
2#或者讀取多個文件對象保存到列表
3fileList = []
4for i in range(3):
5    f = open(str(i)+".txt","w+")
6    f.write("文件名{}.txt".format(i))
7    print(f)
8    fileList.append(f)

9
10#故意不關閉文件為了後面能夠打開文件,用with語句會關閉文件,然後用文件對象處於關閉裝,不能直接通過
11#文件名打開。
12
13#以上創建了三個文件對象,並在文件中寫入文件名
14#接下來將文件解壓到不同變量
15file1, file2, file3 = fileList
16#就看看file3的類型和內容吧
17print(type(file3)) #<class> ,不知道啥玩意,好像和IO輸入輸出類有關係
18print(file1)
19print(file2)
20print(file3)/<class>/<code>

在線教程閱讀:https://python3-cookbook.readthedocs.io/zh_CN/latest/preface.html


分享到:


相關文章: