python習題,關於列表推導式與生成器的練習

列表推導式習題
習題1

s1 = ['alex', 'li', 'WuSir', 'super', 'ab']
過濾掉長度小於3的字符串列表,並將剩下的轉換成大寫字母python

s = [i.upper() for i in s1 if len(i) >= 3]
print(s)
# 運行結果:
# ['ALEX', 'WUSIR', 'SUPER']
習題2

求(x, y)其中x是0-5之間的偶數,y是0-5之間的奇數組成的元組列表面試

lst = [(x, y) for x in range(0, 6, 2) for y in range(1, 6, 2)]
print(lst)
# 運行結果:
# [(0, 1), (0, 3), (0, 5), (2, 1), (2, 3), (2, 5), (4, 1), (4, 3), (4, 5)]
習題3

求m中3, 6, 9組成的列表m= m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]數組

m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
m1 = [i[-1] for i in m]
print(m1)
# 運行結果:
# [3, 6, 9]
習題4

求出50之內能被3整除的數的平方,並放到一個列表中app

lst = [i ** 2 for i in range(1, 51) if i % 3 == 0]
print(lst)
# 運行結果:
# [9, 36, 81, 144, 225, 324, 441, 576, 729, 900, 1089, 1296, 1521, 1764, 2025, 2304]
習題5

構建一個列表:['python1期', 'python2期','python3期', 'python4期', 'python5期', 'python6期', 'python7期', 'python8期', 'python9期', 'python10期' ]函數

lst = [f'python{i}期' for i in range(1, 11)]
print(lst)
# 運行結果:
# ['python1期', 'python2期', 'python3期', 'python4期', 'python5期', 'python6期', 'python7期', 'python8期', 'python9期', 'python10期']
習題6

構建一個列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]測試

# 方法一:
# lst = [i for i in zip(range(6), range(1, 7))]
# print(lst)

# 方法二:
lst = [(i, i + 1) for i in range(6)]
print(lst)
# 運行結果:
# [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
習題7

構建一個列表:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]優化

lst = [i for i in range(0, 19, 2)]
print(lst)
# 運行結果:
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
習題8

有一個列表l1 = ['alex', 'WuSir', '老男孩', '太白']
將其構形成這種列表['alex0', 'WuSir1', '老男孩2', '太白3']spa

l1 = ['alex', 'WuSir', '老男孩', '太白']
lst = [f'{l1[i]}{i}' for i in range(len(l1))]
print(lst)
# 運行結果:
# ['alex0', 'WuSir1', '老男孩2', '太白3']
習題9

有如下數據類型:
x = {'name': 'alex',
'Values': [{'timestamp': 1517991992.94, 'values': 100},
{'timestamp': 1517992000.94, 'values': 200},
{'timestamp': 1517992014.94, 'values': 300},
{'timestamp': 1517992744.94, 'values': 350},
{'timestamp': 1517992800.94, 'values': 280}]}code

將上面的數據經過列表推導式轉換成下面的的類型:[[1517991992.94, 100], [1517992000.94, 200], [1517992014.94, 300], [1517992744.94, 350], [1517992800.94, 280]]對象

x = {'name': 'alex',
     'Values': [{'timestamp': 1517991992.94, 'values': 100},
                {'timestamp': 1517992000.94, 'values': 200},
                {'timestamp': 1517992014.94, 'values': 300},
                {'timestamp': 1517992744.94, 'values': 350},
                {'timestamp': 1517992800.94, 'values': 280}]}
lst = [[i['timestamp'], i['values']] for i in x['Values']]
print(lst)
# 運行結果:
# [[1517991992.94, 100], [1517992000.94, 200], [1517992014.94, 300], [1517992744.94, 350], [1517992800.94, 280]]
習題10

用列表完成笛卡爾乘積
如圖示:

A = {1, 3, 5}
B = {'a', 'b', 'c', 'd'}
AXB = [{(a, b) for a in A for b in B}]
print(AXB)
# 運行結果:
# [(3, 'c'), (5, 'd'), (5, 'c'), (3, 'd'), (3, 'b'), (1, 'd'), (1, 'c'), (3, 'a'), (5, 'b'), (5, 'a'), (1, 'b'), (1, 'a')]
習題11

構建一個列表,列表裏面是三種不一樣尺寸的T恤衫,每一個尺寸都有兩個顏色(列表裏面的元素爲元組類型).
colors = ['black', 'white']
sizes = ['S', 'M', 'L']

colors = ['black', 'white']
sizes = ['S', 'M', 'L']
lst = [(size, color) for size in sizes for color in colors]
print(lst)
# 運行結果:
# [('S', 'black'), ('S', 'white'), ('M', 'black'), ('M', 'white'), ('L', 'black'), ('L', 'white')]
習題12

構建一個列表,列表裏面的元素是撲克牌除去大小王之後,全部的牌類(列表裏面的元素爲元組類型).

l1 = [('A', 'spades'), ('A', 'diamonds'), ('A', 'clubs'), ('A', 'hearts')...('K', 'hearts')]

l1 = [('A', 'spades'), ('A', 'diamonds'), ('A', 'clubs'), ('A', 'hearts'), ('K', 'hearts')]
lst = [(num, color) for num in (list('A') + list(range(2, 11)) + list('JQK')) for color in
       ['spades', 'diamonds', 'clubs', 'hearts']]
print(lst)
# 運行結果:
# [('A', 'spades'), ('A', 'diamonds'), ('A', 'clubs'), ('A', 'hearts'), (2, 'spades'), (2, 'diamonds'), (2, 'clubs'), (2, 'hearts'), (3, 'spades'), (3, 'diamonds'), (3, 'clubs'), (3, 'hearts'), (4, 'spades'), (4, 'diamonds'), (4, 'clubs'), (4, 'hearts'), (5, 'spades'), (5, 'diamonds'), (5, 'clubs'), (5, 'hearts'), (6, 'spades'), (6, 'diamonds'), (6, 'clubs'), (6, 'hearts'), (7, 'spades'), (7, 'diamonds'), (7, 'clubs'), (7, 'hearts'), (8, 'spades'), (8, 'diamonds'), (8, 'clubs'), (8, 'hearts'), (9, 'spades'), (9, 'diamonds'), (9, 'clubs'), (9, 'hearts'), (10, 'spades'), (10, 'diamonds'), (10, 'clubs'), (10, 'hearts'), ('J', 'spades'), ('J', 'diamonds'), ('J', 'clubs'), ('J', 'hearts'), ('Q', 'spades'), ('Q', 'diamonds'), ('Q', 'clubs'), ('Q', 'hearts'), ('K', 'spades'), ('K', 'diamonds'), ('K', 'clubs'), ('K', 'hearts')]
習題13

簡述一下yield與yield from的區別

# yield 例子
def gen1():
    i = 0
    while i < 3:
        yield [3, 5]
        print(f'i:{i}')
        i += 1


g1 = gen1()

for i in g1:
    print(i)


# 運行結果:
# [3, 5]
# i:0
# [3, 5]
# i:1
# [3, 5]
# i:2
# [3, 5]

# yield from 例子
def gen2():
    i = 0
    while i < 3:
        yield from [3, 4, 5]
        print(f'i:{i}')
        i += 1


g2 = gen2()

for i in g2:
    print(i)
# 運行結果:
# 3
# 4
# 5
# i:0
# 3
# 4
# 5
# i:1
# 3
# 4
# 5
# i:2

經過例子能夠看出如下區別:

1.跟的對象不一樣

yield obj: 任意對象

yield from obj:obj必須是[可迭代對象、迭代器、生成器]之一

2.返回的值不一樣

yield obj:返回的是obj整個對象的值

yield from obj:返回的是next(iter(可迭代對象))的下一個值

3.執行順序不一樣

yield obj:
返回obj對象值以後會執行後面的程序

yield from obj:
返回next(iter(可迭代對象))的下一個值後,會繼續取值,只有取值結束纔會繼續執行後面的程序

4.return狀況不一樣

yield obj:
在for循環中,若是取值中遇到return 直接內部會處理StopIteration異常,在while循環中會拋出StopIteration異常,
都得不到return 值

yield from obj:
在遇到生成器的時候,若是遇到return vaule,會把vaule返回給yield from,而後結果賦值給了result,能夠獲得return 返回值

def my_gen():
    i = 0
    while True:
        yield i
        if i == 2:
            return 'my_gen i=2返回'
        i += 1


def gen2():
    result = yield from my_gen()
    print(f'result:{result}')


g2 = gen2()

while True:
    try:
        print(next(g2))
    except StopIteration:
        break
# 運行結果:
# 0
# 1
# 2
# result:my_gen i=2返回
習題14

看下面代碼,可否對其簡化,說說你簡化後的優勢?

# 優化前
def chain(*iterables):
    for it in iterables:
        for i in it:
            yield i


g = chain('abc', (0, 1, 2))
print(list(g))


# 優化後
def chain(*iterables):
    for it in iterables:
        yield from it


g = chain('abc', (0, 1, 2))
print(list(g))

1.優化了空間,提升了效率

2.更精簡更美觀

習題15

看代碼求結果(面試題):

v = [i % 2 for i in range(10)]
print(v)
v = (i % 2 for i in range(10))
print(v)
for i in range(5):
    print(i)
print(i)

結果:
第一個打印結果:
[0,1,0,1,0,1,0,1,0,1]
第二個打印結果:
迭代器對象的地址
第三個打印結果:
0
1
2
3
4
第三個打印結果:
4

習題16

看代碼求結果(面試題):

def demo():
    for i in range(4):
        yield i


g = demo()
g1 = (i for i in g)
g2 = (i for i in g1)
print(list(g1))
print(list(g2))

結果:
第一個打印結果:
[0, 1, 2, 3]
這時候對g1進行生成器g循環取值

第二個打印結果:
[]
next是一個一直向下的過程,
因此當遇到對象g1迭代取值的時候,
也便是對g生成器取值,
以前g對象已經取值結束了,
因此繼續就取不到值了,
因此獲得結果就是該g2迭代器(空值)!

注意:重點記住生成器個一直向下取值(next)的過程,沒法返回!

習題17

看代碼求結果(面試題):

count = 0
t = 0


def add(n, i):
    global count
    count += 1
    print('add', count)
    return n + i


def test():
    global t
    for i in range(4):
        t += 1
        print('test', t)
        yield i


print('start 1')
g = test()
print('start 2')
for n in [1, 10, 5, 2]:
    print('start 4')
    g = (add(n, i) for i in g)
print('start 5')
print(list(g))
print('start 6')
"""
經過增長列表[1,10,5,2]的元素實驗和斷點查看
得出如下結論:
1.首先生成器除非遇到被[list(),for循環,next(),send()]調用,不然是不會執行生成器的!
2.其次生成器在生成的時候,內部是不會執行操做的,相似於def fun()的預加載同樣,
  只是至關於添加了生成了這個生成器的地址
3.在遇到題中
for n in [1, 10, 5, 2]:
    g = (add(n, i) for i in g)
經過斷點看出只是把for n in [1, 10, 5, 2]這個列表的n值傳入進了這個生成器,
這個列表生成器只是參數n修改了,可是並無被執行操做,同時生成器地址變動了,意味着原先的指向已經斷開!
每次循環會新生成一個生成器同時n值也會變動,最後n值是2
4.在執行到list(g)的時候,這個時候查看剛纔說的第一點能夠看出已經執行了內部的調用next()的操做!
5.在執行生成器test()的時候yeild 返回i值 這個時候是0,而後這邊掛起等待另一邊下次調用!
6.在執行add(n, i)的時候,經過斷點和打印的方法確認了一個事實,雖然目前依然沒有明白這個操做的內核,
  因此只能淺顯的經過斷點和打印的效果測試說明下狀況:
  通關斷點和打印能夠看出 這個add(n, i)內的函數被執行了4次。
  這個4次跟咱們的循環的次數是一致了,以前已經經過增減列表的方法測試過,add(n, i)函數的執行次數跟列表成正相關。
7.在執行add(n, i)函數的時候通關斷點查看,這個時候咱們說下每輪的循環值:
  第一輪:n:2 i:0
        return n+i # 2同時這個時候i的值也變成了2
  第二輪:n:2 i:2
        return n+i # 4同時這個時候i的值也變成了4
  第三輪:n:2 i:4
        return n+i # 6同時這個時候i的值也變成了6
  第四輪:n:2 i:6
        return n+i # 8
  當以上4輪循環結束的時候
  能夠回頭看到前面提到第5點,test()從上次掛起的位置繼續執行到yeild i 返回i值 這個時候是1,而後這邊掛起等待另一邊下次調用!
  而後依次循環add(n, i)4次 獲得結果9
  而後繼續執行生成器...............10
  ..............................11
  綜上所述結果是:[8, 9, 10, 11]
  經過執行的結果和順序能夠看出這個過程相似於
***************************************
def test():
    for i in range(4):
        yield i


def add(n, i):
    return n + i


lst = []
g = test()

for i in g:
    for index in range(len([1, 10, 5, 2])):
        i = add([1, 10, 5, 2][-1], i)
    lst.append(i)
print(lst)  # [8, 9, 10, 11]
***************************************
  以上主要是碰到add(n, i)這段循環屢次遇到麻煩卡了不短期,雖然最後只能靠斷點依照狀況描述,可是實際內部狀況,但願知情者能給點幫助謝謝!  
"""
# 運行結果:
# start 1
# start 2
# start 4
# start 4
# start 4
# start 4
# start 5
# test 1
# add 1
# add 2
# add 3
# add 4
# test 2
# add 5
# add 6
# add 7
# add 8
# test 3
# add 9
# add 10
# add 11
# add 12
# test 4
# add 13
# add 14
# add 15
# add 16
# [8, 9, 10, 11]
# start 6
相關文章
相關標籤/搜索