
在日常的情況里面, 是經(jīng)??梢钥匆娦稳鐁et等于的這種表現(xiàn)的。這是一個(gè)列表推導(dǎo)式, 用于計(jì)算列表中每個(gè)元素的平方。這類賦值語句, 對(duì)于從C轉(zhuǎn)行過來的人來說, 不是太容易懂得這種for循環(huán)的用法是怎么一回事, 這也就是為了追求簡(jiǎn)練而被創(chuàng)造出來的一種新式語法。解析式存在如下的一些好處:該解析式被明確地劃分成下述的四種具體情形。接下來會(huì)一個(gè)一個(gè)地說說這四種表達(dá)方式該怎么用。In [1]: lst range(10)In [2]: %%timeit...: ret [x ** 2 for x in lst]...:100000 loops, best of 3: 5.28 μs per loopIn [3]: %%timeit...: ret []...: for x in lst:...: ret.append(x ** 2)...:100000 loops, best of 3: 6.09 μs per loop # 耗時(shí)稍高可以發(fā)現(xiàn)運(yùn)行效率是稍微高出了一點(diǎn), 但是最主要的優(yōu)勢(shì)還是在于代碼的簡(jiǎn)潔性。你可以把列表解析式和if語句搭配在一起用。比如,從列表lst里面把偶數(shù)給挑出來。In [4]: ret []In [5]: for x in lst:...: if x % 2 0:...: ret.append(x) # 使用for循環(huán)...:In [6]: retOut[6]: [0, 2, 4, 6, 8]In [7]: ret [x for x in lst if x % 2 0] # 使用列表解析式In [8]: retOut[8]: [0, 2, 4, 6, 8]列表解析式是能夠像for循環(huán)那樣來使用if語句的。在列表解析式的for語句部分, 是能夠去實(shí)現(xiàn)嵌套操作的。In [9]: (x, y) for x in range(0, 5) for y in range(5, 10)File , line 1(x, y) for x in range(0, 5) for y in range(5, 10)^SyntaxError: invalid syntax# 說明列表解析式一定要使用中括號(hào)括起來In [10]: [(x, y) for x in range(5) for y in range(5, 10)]Out[10]:[(0, 5),(0, 6),(0, 7),(0, 8),(0, 9),(1, 5),(1, 6),(1, 7),(1, 8),(1, 9),(2, 5),(2, 6),(2, 7),(2, 8),(2, 9),(3, 5),(3, 6),(3, 7),(3, 8),(3, 9),(4, 5),(4, 6),(4, 7),(4, 8),(4, 9)]In [11]: ret []In [12]: for x in range(5):...: for y in range(5, 10):...: ret.append((x, y))...:In [13]: retOut[13]:[(0, 5),(0, 6),(0, 7),(0, 8),(0, 9),(1, 5),(1, 6),(1, 7),(1, 8),(1, 9),(2, 5),(2, 6),(2, 7),(2, 8),(2, 9),(3, 5),(3, 6),(3, 7),(3, 8),(3, 9),(4, 5),(4, 6),(4, 7),(4, 8),(4, 9)]單行if語句的寫法, 和列表解析式的寫法, 看起來是非常相似的。這是三目運(yùn)算符的表達(dá)式形式, 也可以寫成x如果cond就輸出y否則的樣子。下面進(jìn)行演示, 這種演示以具體的例子為依托, 具體來說是把偶數(shù)拿來進(jìn)行平方運(yùn)算操作, 而把奇數(shù)拿來進(jìn)行立方運(yùn)算操作。In [14]: ret []In [15]: for x in lst:...: if x % 2 0:...: ret.append(x ** 2)...: else:...: ret.append(x ** 3)...:In [16]: retOut[16]: [0, 1, 4, 27, 16, 125, 36, 343, 64, 729]In [17]: x 3# if特殊用法In [18]: x ** 2 if x % 2 0 else x ** 3Out[18]: 27In [19]: 3 if True else 4Out[19]: 3# 如果采用if特殊用法配合列表解析式 x if cond else y for ...In [20]: [x ** 2 if x % 2 0 else x ** 3 for x in lst]Out[20]: [0, 1, 4, 27, 16, 125, 36, 343, 64, 729]生成器解析式當(dāng)人們看到列表解析式, 它會(huì)直接返回一個(gè)具體的列表, 而生成器解析式的用途不同, 它能夠產(chǎn)生的結(jié)果叫做解析式內(nèi)容, 如果使用者把列表解析式外面的中括號(hào)改換成小括號(hào), 那么得到的東西就是生成器解析式。In [1]: range(10000)Out[1]: range(0, 10000)In [2]: g (x ** 2 for x in range(100000000000))In [3]: gOut[3]: at 0x7f9f08a5f0a0gt;In [4]: next(g)Out[4]: 0In [5]: next(g)Out[5]: 1In [6]: next(g)Out[6]: 4列表解析式和生成器解析式的選擇如果把這個(gè)列表解析式里邊的中括號(hào)給換掉, 換成那種大括號(hào)的話, 這就變成集合解析式了。In [1]: lst [2, 4, 5, 6, 3, 4, 2]In [2]: s {x for x in lst}In [3]: sOut[3]: {2, 3, 4, 5, 6} # 可見列表解析式生成的時(shí)候會(huì)去掉重復(fù)符合集合要求In [4]: type(s)Out[4]: set在利用語法的時(shí)候會(huì)發(fā)現(xiàn)使用字典解析式同樣也需要大括號(hào), 可是需要搞清楚的是與集合解析式的區(qū)別在于對(duì)于表達(dá)式的位置而言并不是單個(gè)元素, 而是把鍵和值組成的對(duì)進(jìn)行放置。In [1]: {str(x): x for x in range(5)}Out[1]: {0: 0, 1: 1, 2: 2, 3: 3, 4: 4}在這四種解析式里, 被用得最廣的還要屬那個(gè)列表解析式。平時(shí)大家經(jīng)常會(huì)碰到一些讓人叫絕的、特別巧妙的用法情況。