溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

8列表解析_生成器表達(dá)式

發(fā)布時間:2020-07-05 13:53:22 來源:網(wǎng)絡(luò) 閱讀:227 作者:chaijowin 欄目:編程語言

?

list comprehension,列表解析:

語法:

[返回值 for 元素 in 可迭代對象 if 條件]

?

注:

列表解析沒有elif,如果有多個條件可用多個if或配合orand使用;

?

列表解析是語法糖:

編譯器會優(yōu)化,不會因?yàn)楹唽懚绊懶?,反而因?yōu)化提高了效率,不僅字節(jié)碼更少,而且減少了棧針;

減少程序員工作量,減少出錯;

簡化了代碼,可讀性增強(qiáng);

?

例:

生成一個列表,元素0-9,對每一個元素自增1后求平方,返回新列表;

[(i+1)**2 for i in range(0,10)]

?

例:

獲取10以內(nèi)的偶數(shù),比較執(zhí)行效率;

方一:

[i for i in range(0,10) if i % 2 == 0]

方二:

even = []

for i in range(10):

??? if not i % 2:?? #常用not這種寫法,同if i % 2 == 0:

??????? even.append(i)

print(even)

?

例:

[0 for _ in range(10)]

[[0] for _ in range(10)]

?

習(xí)題:

1、有這樣的賦值語句:newlist=[print(i) for i in range(10)],newlist的元素打印出的是什么?

In [3]: newlist=[print(i) for i in range(5)]

0

1

2

3

4

In [4]: newlist

Out[4]: [None, None, None, None, None]?? #print(i)是表達(dá)式的結(jié)果或函數(shù)計(jì)算的結(jié)果,print(i)輸出到屏幕了,該列表解析沒有返回值,即最后生成指定個數(shù)的None

?

2、獲取20以內(nèi)的偶數(shù)?如果是3的倍數(shù)也打印?

In [6]: [i for i in range(20) if not i%2]

Out[6]: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

In [7]: [i for i in range(20) if not i%2 or not i%3]?? #list comprehension沒有elif,多個條件用多個if或配合or,and使用

Out[7]: [0, 2, 3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18]

?

3、獲取20以內(nèi)既能被2整除又能被3整除的數(shù)?

方一:

In [7]: [i for i in range(20) if not i%2 and not i%3]

Out[7]: [0, 6, 12, 18]

方二:

In [8]: [i for i in range(20) if not i%2 if not i%3]

Out[8]: [0, 6, 12, 18]

?

列表解析進(jìn)階:

[expr for item in iterable if cond1 if cond2]

等價于

ret=[]

for item in iterable:

???????? if cond1:

?????????????????? if cond2:

??????????????????????????? ret.append(expr)

?

[expr for i in iterable1 for j in iterable2]

等價于

ret=[]

for i in iterable1:

???????? for j in iterable2:

?????????????????? ret.append(expr)

?

例:

In [10]: [(i,j) for i in 'abc' for j in range(3)]

Out[10]:

[('a', 0),

?('a', 1),

?('a', 2),

?('b', 0),

?('b', 1),

?('b', 2),

?('c', 0),

?('c', 1),

?('c', 2)]

In [11]: [[i,j] for i in 'abc' for j in range(3)]

Out[11]:

[['a', 0],

?['a', 1],

?['a', 2],

?['b', 0],

?['b', 1],

?['b', 2],

?['c', 0],

?['c', 1],

?['c', 2]]

In [12]: [{i:j} for i in 'abc' for j in range(3)]

Out[12]:

[{'a': 0},

?{'a': 1},

?{'a': 2},

?{'b': 0},

?{'b': 1},

?{'b': 2},

?{'c': 0},

?{'c': 1},

?{'c': 2}]

?

習(xí)題:

(1)如下語句的輸出?

In [17]: [(i,j) for i in range(7) for j in range(20,25) if i>4 if j>23]

Out[17]: [(5, 24), (6, 24)]

In [18]: [(i,j) for i in range(7) if i>4 for j in range(20,25) if j>23]

Out[18]: [(5, 24), (6, 24)]

In [19]: [(i,j) for i in range(7) for j in range(20,25) if i>4 and j>23]?? #常用此種

Out[19]: [(5, 24), (6, 24)]

?

(2)返回110平方的列表?

In [20]: [i**2 for i in range(1,11)]

Out[20]: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

?

(3)lst=[1,4,9,16,2,5,10,15],生成一個新列表,要求新列表元素是lst相鄰兩項(xiàng)之和?

lst = [1,4,9,16,2,5,10,15]

[lst[i]+lst[i+1] for i in range(len(lst)-1)]

?

(4)打印九九乘法表?

[print('{}*{}={:<3}{}'.format(j,i,i*j,'\n' if i==j else ''),end='') for i in range(1,10) for j in range(1,i+1)]

?

(5)'0001.abadicddus'ID格式,要求ID格式以點(diǎn)號分割,左邊是4位從1開始的整數(shù),右邊是10位隨機(jī)小寫英文字母,請依次生成前100ID的列表?

方一:

import random

['{:04}.{}'.format(i,''.join([chr(random.randint(97,122)) for _ in range(10)])) for i in range(1,101)]

方二:

import random

import string

['{:04}.{}'.format(i,''.join([random.choice(string.ascii_lowercase) for _ in range(10)])) for i in range(1,101)]

方三:

import random

['{:04}.{}'.format(i,''.join([random.choice(bytes(range(97,123)).decode()) for _ in range(10)])) for i in range(1,101)]

?

注:

ascii,american standard code for information interchange,美國信息交換標(biāo)準(zhǔn)代碼;

小寫a-z對應(yīng)ascii碼的97-122;

ascii碼表的0-127常用,0-9,\t,\n,\r,space對應(yīng)的ascii;

chr(),將ascii碼對應(yīng)的數(shù)字轉(zhuǎn)為字符;

0-31,12733個控制字符,或通信專用字符;

32-126,95個字符;

32,空格;

48-57,0-9數(shù)字;

65-90,26個大寫英文字母;

97-122,26個小寫英文字母;

8,退格;

9,制表;

10,換行;

13,回車;

?

?

?

generator expression,生成器表達(dá)式:

語法:

(返回值 for 元素 in 可迭代對象 if 條件)

列表解析的[]換為()即可;

返回一個生成器;

?

list comprehension區(qū)別:

generator expression是按需計(jì)算,或稱惰性求值(延遲計(jì)算,python思想),需要的時候才計(jì)算值,不需要的時候給個對象(可理解為中間狀態(tài),是一種可迭代對象);

list comprehension是立即返回值;

預(yù)計(jì)算和延遲計(jì)算,都有應(yīng)用場景;

?

生成器:

iterable,可迭代對象;

iterator,迭代器;

iterable不一定是iterator,iterator一定是iterable

next(),用next()方法測試是否是iterator

在迭代時最好用for控制,如果直接用next()要控制好邊界,否則拋異常;

迭代完后,不能回頭;

?

生成器總結(jié):

延遲計(jì)算;

返回迭代器,可以迭代;

從前到后走完一遍后,不能回頭;

?

列表解析總結(jié):

立即計(jì)算;

返回的不是迭代器,返回可迭代對象列表;

從前到后走完一遍后,可重新回頭迭代;

?

例:

In [1]: [i for i in range(5)]

Out[1]: [0, 1, 2, 3, 4]

In [2]: (i for i in range(5))

Out[2]: <generator object <genexpr> at 0x7fc6440cc9e8>

In [3]: for x in (i for i in range(5)):

?? ...:???? print(x)

?? ...:????

0

1

2

3

4

In [11]: g=('{:04}'.format(i) for i in range(1,4))

In [12]: next(g)??

Out[12]: '0001'

In [13]: next(g)

Out[13]: '0002'

In [14]: next(g)

Out[14]: '0003'

In [15]: next(g)

---------------------------------------------------------------------------

StopIteration???????????????????????????? Traceback (most recent call last)

<ipython-input-15-e734f8aca5ac> in <module>()

----> 1 next(g)

StopIteration:

In [16]: g=('{:04}'.format(i) for i in range(1,4))?? #iterator最好用for控制

In [17]: for i in g:

??? ...:???? print(i)

??? ...:????

0001

0002

0003

In [23]: lc=['{:04}'.format(i) for i in range(5)]

In [25]: for x in lc:

??? ...:???? print(x)

??? ...: print('############')

??? ...: for x in lc:

??? ...:???? print(x)

??? ...:????

0000

0001

0002

0003

0004

############

0000

0001

0002

0003

0004

?

?

習(xí)題:

it=(print('{}'.format(i+1)) for i in range(2))

first=next(it)

second=next(it)

val=first+second

val的值是什么??? #報錯,print()語句是輸出到控制臺,該生成器返回值為None

val=first+second語句之后,能否再次next(it)??? #不能

In [18]: it=(print('{}'.format(i+1)) for i in range(2))

In [19]: type(it)

Out[19]: generator

In [20]: first=next(it)

1

In [21]: second=next(it)

2

In [22]: val=first+second

---------------------------------------------------------------------------

TypeError?? ??????????????????????????????Traceback (most recent call last)

<ipython-input-22-663c3b91df51> in <module>()

----> 1 val=first+second

TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'

?

生成器表達(dá)式和列表解析式的對比:

計(jì)算方式,生成器表達(dá)式延遲計(jì)算,列表解析式立即計(jì)算;

內(nèi)存占用,單從返回值本身來說,生成器表達(dá)式省內(nèi)存,列表解析式返回新的列表(構(gòu)造出新的列表,需占用內(nèi)存);生成器沒有數(shù)據(jù),內(nèi)存占用極少,但使用時,雖然一個個返回數(shù)據(jù),但合起來占用的內(nèi)存也差不多;

計(jì)算速度,單從計(jì)算時間看,生成器表達(dá)式耗時非常短,列表解析式耗時時間長;但是生成器本身并沒有返回任何值,只返回了一個生成器對象;列表解析式構(gòu)造并返回了一個新的列表;

?8列表解析_生成器表達(dá)式

?

集合解析式:

語法:

{返回值 for 元素 in 可迭代對象 if 條件}

{}

立即返回一個集合;

?

例:

In [26]: {(x,x+1) for x in range(5)}

Out[26]: {(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)}

In [27]: {[x] for x in range(5)}

---------------------------------------------------------------------------

TypeError???????????????????????????????? Traceback (most recent call last)

<ipython-input-27-a39ffa943c7e> in <module>()

----> 1 {[x] for x in range(5)}

<ipython-input-27-a39ffa943c7e> in <setcomp>(.0)

----> 1 {[x] for x in range(5)}

TypeError: unhashable type: 'list'

?

字典解析式:

語法:

{返回值 for 元素 in 可迭代對象 if 條件}

{},用key:value形式;

立即返回一個字典;

?

例:

In [28]: {x:(x,x+1) for x in range(5)}

Out[28]: {0: (0, 1), 1: (1, 2), 2: (2, 3), 3: (3, 4), 4: (4, 5)}

In [29]: {x:[x,x+1] for x in range(5)}

Out[29]: {0: [0, 1], 1: [1, 2], 2: [2, 3], 3: [3, 4], 4: [4, 5]}

In [30]: {[x]:[x,x+1] for x in range(5)}

---------------------------------------------------------------------------

TypeError???????????????????????????????? Traceback (most recent call last)

<ipython-input-30-32f94dcaf39f> in <module>()

----> 1 {[x]:[x,x+1] for x in range(5)}

<ipython-input-30-32f94dcaf39f> in <dictcomp>(.0)

----> 1 {[x]:[x,x+1] for x in range(5)}

TypeError: unhashable type: 'list'

In [31]: {(x,):[x,x+1] for x in range(5)}

Out[31]: {(0,): [0, 1], (1,): [1, 2], (2,): [2, 3], (3,): [3, 4], (4,): [4, 5]}

In [32]: {chr(0x41+x):x**2 for x in range(5)}

Out[32]: {'A': 0, 'B': 1, 'C': 4, 'D': 9, 'E': 16}

In [33]: {str(x):y for x in range(3) for y in range(4)}?? #等價于如下

Out[33]: {'0': 3, '1': 3, '2': 3}

In [34]: ret={}

In [36]: for i in range(3):

??? ...:???? for j in range(4):

??? ...: ????????ret[str(i)]=j

??? ...:????????

??? ...:????????

In [37]: ret

Out[37]: {'0': 3, '1': 3, '2': 3}

?

python2引入列表解析式;

python3引入生成器表達(dá)式;

python3引入集合解析式、字典解析式、并遷移到了2.7

一般來說,要多應(yīng)用解析式、簡短、高效;

如果一個解析式非常復(fù)雜,難以讀懂,要考慮拆解成for循環(huán);

生成器和迭代器是不同的對象,但都是可迭代對象;

?

iter(iterable),將一個可迭代對象封裝成一個迭代器;

next(iterator),取元素,對一個迭代器取下一個元素,如果元素全部取完,再next()會拋StopIteration異常;

?

可迭代對象:

能夠通過迭代一次次返回不同元素的對象,所謂相同不是指值是否相同,而是元素在容器中是否是同一個,如list中值可重復(fù);

可以迭代,但是未必有序,未必可索引;

可迭代對象有,list,tuple,string,bytes,bytearray,range,set,dict,iterator等;

可用成員運(yùn)算符in,not inin本質(zhì)上就是在遍歷對象;

?

迭代器:

特殊的對象,一定是可迭代對象,具備可迭代對象的特征;

通過iter(iterable)把一個可迭代對象封裝成迭代器;

通過next()迭代迭代器對象;

生成器對象,就是迭代器對象;

迭代器不一定是生成器;

?

?

?


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI