寫在之前
大家好,這裡是零基礎學習 Python 系列,在這裡我將從最基本的Python 寫起,然後再慢慢涉及到高階以及具體應用方面。我是完全自學的 Python,所以很是明白自學對於一個人的考驗,所以在這裡我會盡我最大的努力,把 Python 儘可能簡單的表述清楚,讓更多想要學習 Python 的朋友能夠入門。同時寫這個教程也算是對自己之前所學知識的一個鞏固和提高,喜歡的朋友們可以點個關注,有問題歡迎隨時和我交流。本文所有的代碼編寫均是Python3 版本。
推導式是從一個或多個迭代器快速簡潔的創建數據結構的一種辦法,它可以將循環和條件判斷結合,從而可以避免語法冗長的代碼。
列表推導式
我在之前的文章中(零基礎學習 Python 之 for 循環語句)寫過列表推導式,但是寫的相對簡單,今天我準備再詳細說一下,會的權當複習,不會的正好學習。
如果讓你創建一個從 0 到 5 的整數列表,按照我們之前學過的方法,你可以這樣:
>>> my_list = []>>> my_list.append(0)>>> my_list.append(1)>>> my_list.append(2)>>> my_list.append(3)>>> my_list.append(4)>>> my_list.append(5)>>> my_list[0, 1, 2, 3, 4, 5]
如果用我們前天學過的 for 循環,你可以這樣:
>>> my_list = []>>> for i in range(0,6):... my_list.append(i)... >>> my_list[0, 1, 2, 3, 4, 5]
上面的兩個方法都是可行的 Python 方法,得到的都是相同的結果,但是這都不是最像 Python 風格的創建列表的方式,什麼是 Python 風格?當然是簡潔優雅!請看下面:
>>> my_list = [i for i in range(0,6)]>>> my_list[0, 1, 2, 3, 4, 5]
看完這種方法,再比較之前的那兩種方法,列表推導的優點一目了然。
在第一行中,第一個變量 i 為列表的生成值,換句話說,就是將循環的結果放在列表 my_list 中,第二個 i 是循環變量,這裡要提一點的是,第一個變量 i 可以是表達式,請看下面的例子:
>>> my_list = [i*i for i in range(0,6)]>>> my_list
除了上面第一個變量可以是表達式以外,列表推導式也可以加上條件表達式,請看下面的例子:
>>> my_list = [i for i in range(0,6) if i % 2 == 1]>>> my_list[1, 3, 5]
上述的例子通過列表推導式得到一個 0 到 5 之間的奇數列表,是不是要比傳統的方法簡潔很多呢?所以,現在你是不是該動動手指寫一個傳統的求奇數列表的例子來對比對比呢?
上面我們用的一直是一個 for 循環的例子,那如果是雙層 for 循環呢?
>>> first = range(1,4)>>> second = range(7,9)>>> for i in first:... for j in second:... print(i,j)... 171827283738
如果是上面這個例子,你該怎麼用列表推導式呢?如果你思考完,請看下面的答案:
>>> first = range(1,4)>>> second = range(7,9)>>> results = [(i,j) for i in first for j in second]>>> for result in results:... print(result)... (1, 7)(1, 8)(2, 7)(2, 8)(3, 7)
我在這將上面的例子用了元組輸出,具體用什麼形式,看當時的情況和自己的心情。
字典推導式
除了列表,字典其實也有自己的推導式,它和列表推導式其實有些相似,也有 if 條件判斷以及多個 for 循環的迭代語句,下面舉個最簡單的例子:
>>> words = 'rocky like python'>>> letter_cnt = {letter:words.count(letter) for letter in words}>>> letter_cnt{'r': 1, 'o': 2, 'c': 1, 'k': 2, 'y': 2, ' ': 2, 'l': 1, 'i': 1, 'e': 1, 'p': 1, 't': 1, 'h': 1, 'n': 1}
上面的例子是計算句子裡每個字母出現的個數,但是不知道你有沒有發現,有些重複的字母的次數出現了多次?還記得怎麼解決掉字符串裡重複的字母麼?是 set 啊,快點動手試試吧。
集合推導式
集合也不例外,也有自己的推導式,也是跟上面的列表推導式和字典推導式類似,不只是在簡單的,或者是帶條件判斷的都是如此,請看下面的例子:
>>> my_set = {i for i in range(0,6) if i % 3 == 1}>>> my_set{1, 4}
生成器推導式
我們說了三個,是不是掉了什麼?對,是存在感最不強的元組,那么元組推導式是什麼樣子的呢?你肯定想說:「簡單!不就是把列表推導式的方括號變成圓括號不就得了麼?!」,其實我想告訴你的事,確實有圓括號的推導式,但不是元組的,因為元組沒有推導式!圓括號的那個推導式是生成器推導式,不信的話請看下面的例子:
>>> my_exp = (i for i in range(0,6))>>> my_exp<generator object <genexpr> at 0x110090308>>>> type(my_exp)<class 『generator'>
你現在只需要知道生成器是將數據傳給迭代器的一種方式就好了,至於生成器我在之後的文章中會詳細講到,盡情期待。
雖然我們還沒學生成器這個概念,但是不妨礙我們學習這個推導式,你可以直接對生成器的對象進行迭代,比如像下面一樣:
>>> for exp in my_exp:... print(exp)... 012345
作為一個每個知識點都想寫的人來說,這裡勞煩大家再記住一點的是,一個生成器只能生成一次,如果想再生成一次的話,你會發現它消失掉了,什麼意思呢,看下面的例子:
>>> second_exp = list(my_exp)>>> second_exp[]
現在生成器先記住這些就可以,記不住也沒關係,我還會細講生成器,我們到時候再討論。
寫在最後