推導式是從一個或多個迭代器快速簡潔的建立數據結構的一種辦法,它能夠將循環和條件判斷結合,從而能夠避免語法冗長的代碼。python
我在以前的文章中(零基礎學習 Python 之 for 循環語句)寫過列表推導式,可是寫的相對簡單,今天我準備再詳細說一下,會的權當複習,不會的正好學習。bash
若是讓你建立一個從 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 循環,你能夠這樣:app
>>> 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]
複製代碼
看完這種方法,再比較以前的那兩種方法,列表推導的優勢一目瞭然。ui
在第一行中,第一個變量 i 爲列表的生成值,換句話說,就是將循環的結果放在列表 my_list 中,第二個 i 是循環變量,這裏要提一點的是,第一個變量 i 能夠是表達式,請看下面的例子:spa
>>> my_list = [i*i for i in range(0,6)]
>>> my_list
複製代碼
除了上面第一個變量能夠是表達式之外,列表推導式也能夠加上條件表達式,請看下面的例子:code
>>> my_list = [i for i in range(0,6) if i % 2 == 1]
>>> my_list
[1, 3, 5]
複製代碼
上述的例子經過列表推導式獲得一個 0 到 5 之間的奇數列表,是否是要比傳統的方法簡潔不少呢?因此,如今你是否是該動動手指寫一個傳統的求奇數列表的例子來對比對比呢?cdn
上面咱們用的一直是一個 for 循環的例子,那若是是雙層 for 循環呢?對象
>>> first = range(1,4)
>>> second = range(7,9)
>>> for i in first:
... for j in second:
... print(i,j)
...
1 7
1 8
2 7
2 8
3 7
3 8
複製代碼
若是是上面這個例子,你該怎麼用列表推導式呢?若是你思考完,請看下面的答案:
>>> 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)
...
0
1
2
3
4
5
複製代碼
做爲一個每一個知識點都想寫的人來講,這裏勞煩你們再記住一點的是,一個生成器只能生成一次,若是想再生成一次的話,你會發現它消失掉了,什麼意思呢,看下面的例子:
>>> second_exp = list(my_exp)
>>> second_exp
[]
複製代碼
如今生成器先記住這些就能夠,記不住也不要緊,我還會細講生成器,咱們到時候再討論。
更多內容,歡迎關注公衆號「Python空間」,期待和你的交流。