python -- 生成器和各類推導式

1、生成器
 
        一、生成器的本質就是迭代器,一個一個的建立對象
        二、建立生成器的方式
            一、生成器函數
            二、經過生成器表達式來獲取生成器
            三、經過數據的轉化也能夠獲取生成器
2、生成器函數
        生成器函數中包含yield,返回數據和return差很少
不一樣點:
        return 會當即結束這個函數的執行
        yield能夠分段的執行一個函數
 
  
def func():
    print('今每天氣如何?')
    yield '晴天'
    print('明每天氣如何?')
    yield '陰天'
    print('後每天氣怎麼樣')
    yield '誰知道呢'

ret = func() # 執行函數,此時沒有運行函數,此時拿到的是一個生成器
print('返回值是:',ret) # 返回值是: <generator object func at 0x000001AA87C45BA0>

print(ret.__next__()) # 第一次執行__next__的時候,函數纔開始執行
print(ret.__next__()) # 執行下一個yield
print(ret.__next__()) # StopInteration
生成器函數能向下執行到兩個條件:
 
 一、 __next__(),執行到下一個yield
 二、send(),執行到下一個yield,給上一個yield位置傳值
  
  全部的生成器都是迭代器均可以使用for循環
  均可以使用list()函數來獲取到生成器內的全部元素
例子
第一種
# 買100件衣服
def buy():
    st = []
    for i in range(1,101):
        lst.append("衣服%s"% i)
    return lst

lst = buy()
print(lst)

第二種 用生成器
def buy():
    for i in range(101):
    yield "衣服%s"%i

gen = buy() #生成器或者迭代器的好處:節省內存
print(gen.__next__()) # 須要一件拿一件
print(gen.__next__())
print(gen.__next__())


for yifu in gen: # 迭代器.__next__()
    print(yifu)

lst = list(gen) # 內部使用的是for 循環 ->__next__()
print(lst)

send()  執行到下一個yield,給上一個yield位置傳值面試

def func():
  print('你喜歡什麼水果')
  a = yield "芒果"
  print("a", a)
  b = yield "蘋果"
  print("b", b)
  c = yield "柚子"
  print("c",c)

gen = func()

print(gen.__next__())
print(gen.__next__())
print(gen.__next__())

# 你喜歡什麼水果
# 芒果
# a None
# 蘋果
# b None
# 柚子
結論:執行函數時,a,b,c 都返回None

gen = func()

print(gen.__next__()) # 第一個位置用send沒有任何意義
print(gen.send("籃球")) # 給上一個yield位置傳值
print(gen.send("足球"))

# 你喜歡什麼水果
# 芒果
# a 籃球
# 蘋果
# b 足球
# 柚子
 生成器中記錄的是代碼而不是函數的運做
def func():
    print('哈哈')
    yield ''大風
 
gen = func() #  建立生成器,此時運行會把生成器函數中的代碼記錄在內存
 
     當執行到__next__(),運行此空間中的代碼,運行到yield結束
 
   優勢:節省內存,生成器自己就是代碼,幾乎不佔內存
    特色:惰性機制,只能向前,不能反覆
 
3、各類推導式
 
    一、列表推導式  [結果 for循環 if判斷]
# 生成列表.類表中裝的數據是 1-100之間全部的偶數的平方
lst =[i ** 2 for i in range(1,101) if i %2 == 0]
print(lst)

 

# # 尋找名字中帶有兩個e的人的名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]

lst = [name for first in names for name in first if name.count("e") == 2]
print(lst)

二、字典推導式{結果(k,v)for 循環 if判斷} app

# 把字典的key和value互換, 生成新字典
dic = {"主食": "炒麪", "副食": "小拌菜", "":"疙瘩湯"}
dic1 = {v:k for k,v in dic.items() }
print(dic1)
三、集合推導式 {結果(k) for 循環 if 判斷}
 
      沒有元組推導式
 
4、生成器表達式
 
    (結果  for 循環  if)
g = (i for i in range(10)) # 生成器表達式
print(g) # <generator object <genexpr> at 0x000001F7769F5938>

yield from  # 能夠把一個可迭代對象分別進行yield返回 函數

def func():
  lst = ["水果%s"% i for i in range(10)]
  yield from lst

gen = func()

ret = gen.__next__()
print(ret)
ret = gen.__next__()
print(ret)

# 水果0
# 水果1

添加 寫代碼的注意事項 spa

def func(name,info):
'''
    函數功能
    :param name: 參數name
    :param info: 參數 info
    :return: 返回什麼內容
    :creator:建立者
    :author :做者
    :date:時間
'''

a = func
print("***")
print("***")
print("***")
print("***")
...


a('','') # 中間的代碼內容過長,查找a的名字
print(a.__name__) # 看到函數的真實的名字(相對)
print(a.__doc__) # 函數的功能
面試相關的有坑的題
 
深坑,須要值的時候纔去拿值
def func():
    print(111)
    yield 222

g = func() # 建立生成器
g1 = (i for i in g) # 生成器表達式,生成器g1,g1的數據來源於g
g2 = (i for i in g1) # 生成器表達式 生成器g2,g2的數據來源於g1

print(list(g)) # 獲取g中的數據,這時func()纔會被執行,打印111,獲取222,g完畢
print(list(g1)) # 獲取g1的數據,g1的數據來源時g,可是g已經被取完了,全部g1沒有數據
print(list(g2)) # 與g1同理
# 以下代碼打印的結果分別是什麼
def extendList(val,list=[]): # 屢次調用使用同一個列表
    print(id(list))
    list.append(val) # 把元素添加到列表,而後返回列表
    return list
list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList("a")

print("list1 = %s"%list1)
print("list2 = %s"%list2)
print("list3 = %s"%list3)


# list1 = [10, 'a']
# list2 = [123]
# list3 = [10, 'a']
相關文章
相關標籤/搜索