摘要:開始本文主要記錄廖大教程中高級特性這一節的內容,并寫下我的一些理解。廖大的教程中是這樣說的函數是順序執行,遇到語句或者最后一行函數語句就返回。
前言
用 python 差不多半年多了,從去年暑假開始接觸,從開始的懵逼,到寫了一些小爬蟲總算入門之后,許多作業也是能用 python 就用 python,基本拋棄了 C++。但是還是有些過于急躁了,能夠寫一些簡短的代碼,但是對于 python 的很多特性都不知道或者忘記了,這里回去廖大教程復習一下,順便記錄下我覺得比較重要的地方。
開始本文主要記錄廖大教程中高級特性這一節的內容,并寫下我的一些理解。在我看來,這些特性是很 pythonic 的,用在代碼中很有 bigger 啊~
列表生成式(List Comprehensions)切片和迭代就不說了,這里直接先看一下列表生成式吧,從名字就能大概猜出這是生成列表的一些方法,比如:如何生成[1*1, 2*2, ... ,10*10]?可以用循環不斷向列表尾部添加元素,如果使用 pythonic 的方法,也就是列表生成式,則是:
>>> [x * x for x in range(1, 11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
后面還能跟上 if 判斷,例如:
>>> [x * x for x in range(1, 11) if x%2==0] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
這樣,本來需要使用循環寫4,5行的代碼,使用一行就解決了,直觀明了。
還能使用兩個 for 循環生成全排列:
>>> [m + n for m in "ABC" for n in "XYZ"] ["AX", "AY", "AZ", "BX", "BY", "BZ", "CX", "CY", "CZ"]
這樣如何添加 if 判斷呢?可以在每個 for 語句后添加,或者在最后添加:
>>> [m + n for m in "ABC" if m < "C" for n in "XYZ" if n < "Z"] ["AX", "AY", "BX", "BY"] >>> [m + n for m in "ABC" for n in "XYZ" if n < "Z" and m < "C"] ["AX", "AY", "BX", "BY"]
也可以同時在一個 for 語句中迭代多個變量,比如dict的items()可以同時迭代key和value:
>>> d = {"x": "A", "y": "B", "z": "C" } >>> [k + "=" + v for k, v in d.items()] ["y=B", "x=A", "z=C"]
差不多就是這樣了~
但是以前總是寫 C++ ,這種思維模式很難改過來,只能慢慢在使用中熟悉這種語法,習慣了就能夠在下意識中寫出來了。
生成器(Generator)為什么要使用生成器?廖大的教程中說得很詳細,這里再簡述一下:
因為列表的內容放在內存中,而受到內存限制,列表的容量有限。
如果我們只訪問極少的元素,那么存在極大的空間浪費。
而生成器可以一邊迭代一邊計算下一個值,理論上,該過程可以無限進行下去,并且不會占用大量內存。
這里只是簡單介紹一下,更詳細的請 Google 哈~
如何創建生成器?第一種方法類似于前面講到的列表生成式,只需要將[]改為()即可:
>>> L = [x * x for x in range(10)] >>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> g = (x * x for x in range(10)) >>> gat 0x1022ef630>
可以看到,方法上大致相同,[]得到的是一個已經得到所有值的列表,()得到的是一個生成器,它們都能使用 for 循環來迭代,但是生成器不能使用下標訪問,并且只能被迭代一次,再次迭代則會有 StopIteration 的異常:
>>> for i in g: ... print(i) ... 0 1 4 9 16 25 36 49 64 81 >>> for i in g: ... print(i) ... >>> next(g) Traceback (most recent call last): File "", line 1, in StopIteration
不過當我們創建了一個generator后,基本上永遠不會調用next(),而是通過for循環來迭代它,并且不需要關心StopIteration的錯誤。
如果推算的算法比較復雜,用類似列表生成式的for循環無法實現的時候,還可以用函數來實現,比如,著名的斐波那契數列:
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return "done"
關于 yield 這個關鍵字,我在剛學 python 的時候也糾結了很久,直到看到生成器的時候才大致明白,大家搜索一下就能大致明白了,我覺得這東西說起來麻煩,只說一兩句又怕說錯。廖大的教程中是這樣說的:
函數是順序執行,遇到return語句或者最后一行函數語句就返回。而變成generator的函數,在每次調用next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。
可能有點難理解,不過明白了就很好說了。
當然,函數中還可以添加 return,在一個 generator function 中,如果沒有 return,則默認執行至函數完畢,如果在執行過程中 return,則直接拋出 StopIteration 終止迭代。
例如上面的例子,我們在迭代時發現并沒有出現 "done" 這串字符,是因為 return 的值被當作 Exception Value 了,如果要顯示出來,則可以這樣:
>>> g = fib(6) >>> while True: ... try: ... x = next(g) ... print("g:", x) ... except StopIteration as e: ... print("Generator return value:", e.value) ... break ... g: 1 g: 1 g: 2 g: 3 g: 5 g: 8 Generator return value: done迭代器(Iterator)
可直接作用于 for 循環的對象被稱為可迭代對象,可以用 isinstance() 函數判斷是否為可迭代對象:
>>> from collections import Iterable >>> isinstance([], Iterable) True >>> isinstance({}, Iterable) True >>> isinstance("abc", Iterable) True >>> isinstance((x for x in range(10)), Iterable) True >>> isinstance(100, Iterable) False
而可以被next()函數調用并不斷返回下一個值的對象稱為迭代器:Iterator。當然,仍然可以使用isinstance()判斷一個對象是否是Iterator對象:
>>> from collections import Iterator >>> isinstance((x for x in range(10)), Iterator) True >>> isinstance([], Iterator) False >>> isinstance({}, Iterator) False >>> isinstance("abc", Iterator) False
通過上面兩個例子,可以這樣理解:生成器和 list,tuple,str 等都是 Iterable 對象,生成器同時還是 Iterator 對象,而 list 等不是。那么能否直接將 Iterable 對象轉換成 Iterator 對象呢?
可以使用iter()函數:
>>> isinstance(iter([]), Iterator) True >>> isinstance(iter("abc"), Iterator) True
其實,Iterator 對象表示的是一個數據流,我們可以把這個數據流看做是一個有序序列,但卻不能提前知道序列的長度,只能不斷通過next()函數實現按需計算下一個數據,所以 Iterator 的計算是惰性的,只有在需要返回下一個數據時它才會計算。Iterator甚至可以表示一個無限大的數據流,但 list,tuple 什么的是不可能這樣的。
總結過了個寒假沒碰代碼,相當于復習了一遍啊,其實這里說到的特性是很淺顯的,理解起來不難,等全部差不多復習完還得再深入一點,理解更多才行。
以上~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38411.html
摘要:關于作者是軟件基金會的成員,也是巴西第一個黑客空間的聯合創始人。他曾在巴西媒體,銀行和政府部門教授開發,并在,,和上發表演講。他是一位自學成才的程序員,也是使用學習編程一系列書的作者。 showImg(https://segmentfault.com/img/remote/1460000018926735); 來源 | 愿碼(ChainDesk.CN)內容編輯 愿碼Slogan | ...
摘要:但是相對于開發者來說語言提供了更加強大的支持。自身的強類型的機制異常處理垃圾自動收集等是其程序健壯性的重要保證。框架的設計理念也遵循了優雅明確簡單,并具有簡潔易讀及可拓展性。 關于Python的發展,及Python的歷史概述我這里將不會浪費時間和大家介紹,因為我覺得能夠借用搜索引擎搜索到的知識大家就竟可能的自己動手動腦去了解和認知,我主要就講講Python的一些基本的特性及版本的選擇相...
摘要:盡管如此,還具有高級的數據類型和靈活性。它配備了大量的標準模塊,可用于程序庫。一些模塊提供如下功能通過這些很贊的特性,瞬時化身為面向過程的語言。開發者可以便捷地將解釋器連接到一個使用編寫的應用程序,并能隨時用作擴展。下一部分會繼續分享。 【編者按】本文作者是 Abhishek Jaiswal ,擅長 .NET、C#、Python 等多種語言的技術控。本文中,作者通過活潑有趣的口吻向大家...
摘要:所以如果像上述這樣引入模塊的時候,調用函數必須加上模塊名通常情況下鼓勵每個語句只導入一個包方便理解和閱讀代碼。 今天我們學習Python的高級特性、模塊和IO操作,通過學習這些,我們可以更快的了解Python,使用Python。 高級特性中會講述列表生成式、生成器、和一些高級函數,學習這些方便我們快速的生成列表,節省我們使用Python的時間,更快的使用Python達成我們的目的。 模...
閱讀 3717·2021-10-11 10:59
閱讀 1301·2019-08-30 15:44
閱讀 3479·2019-08-29 16:39
閱讀 2888·2019-08-29 16:29
閱讀 1800·2019-08-29 15:24
閱讀 808·2019-08-29 15:05
閱讀 1264·2019-08-29 12:34
閱讀 2302·2019-08-29 12:19