列表推導式+lambda表示式的激情
Python這麼優雅的語言,我也是醉了......
事情由一段程式碼引發,請看:
上述的列表推導式+lambda表示式+for迴圈,他們碰撞出來的結果搞的人暈頭轉向,咱們逐步來分析一下他們到底是個什麼鬼。
lambda表示式可以表示成:
def func(x):
return x*i
加上for迴圈:
for i in range(10):
def func(x):
return x*i
加上列表推導式: # 註釋一
到此,就可以看清楚他的結構了,funcs函式裡面形成了一個閉包li = [] def funcs(): for i in range(10): def func(x): return x*i li.append(func) return li funcs()
閉包的兩個特性:
①、內部函式使用外部函式的變數(不對外部函式的變數進行重新賦值)
②、外部函式 return 內部函式的函式名(其實是返回內部函式的記憶體地址)
對上面的函式進行簡化:去掉for迴圈,使用單個變數代替,去掉 列表 li 直接返回內部函式名,它就變成了下面這個樣子
def funcs():
i=9 # 定義了變數,也稱為內部函式的環境變數,它不會改變,不被外界影響
def func(x):
return x*i # 使用了外部函式的變數
return func # 返回了內部函式
簡單理解:閉包 = 內部函式 + 環境變數
閉包的特性:當內部函式返回的時候,會把連同內部函式定義時候的環境變數一同返回
瞭解了閉包,在來看結果為什麼全都是18,而不是預期結果:
①區分內部函式的定義和呼叫:
當我們只到是定義了外部和內部函式,呼叫了外部函式,並未呼叫內部函式,也就是到註釋一
for迴圈的作用就是建立10個函式,最後 i 的取值是9
所以我們獲得了類似下面的圖譜:
當我們進行內部函式呼叫的時候,此時的情形是:
有一個包含10個函式的列表,變數 i=9
再加上閉包的特性,i 會隨著內部函式的一同返回,所以呼叫依次內部函式的時候,情形就成了下面這樣:以呼叫第1個函式為例
所以結果就成了 2 * 9 = 18
再呼叫別的內部函式都是如此邏輯。
知乎中此問題的回答者 @Op小劍 提到了延遲繫結
匿名函式的 i 並不是依次順序指向0,1,2,...的,因為在迭代的過程中,建立匿名函式→建立完成後→才去找i 指向的值。
對上圖做了很好的詮釋當我們將表示式修改為下面的樣子,預期結果就出現了:
li = []
def funcs():
for i in range(10):
def func(x, i=i): # 給內部函式傳參, i 是內部函式的區域性變數,當所有內部函式定義完畢,i 的值也變成了一個列表(range(10))
return x*i # 呼叫的時候其實是呼叫的內部函式的值
li.append(func)
return li
for func in funcs():
func(2)
修改到列表推導式+lambda表示式就是下面的情況:
funcs = [lambda x, i=i: x*i for i in range(10)]
for func in funcs:
print(func(2))
此時呼叫的情形就像下面的圖譜:
到此,此問題就分析結束了,涉及到的變數作用域,就不分析了,大家可以自行百度去理解。
相關推薦
列表推導式+lambda表示式的激情
Python這麼優雅的語言,我也是醉了......事情由一段程式碼引發,請看:上述的列表推導式+lambda表示式+for迴圈,他們碰撞出來的結果搞的人暈頭轉向,咱們逐步來分析一下他們到底是個什麼鬼。lambda表示式可以表示成:def func(x): return
python迭代器-生成器-列表推導式-生成器表示式-day11-12
生成器Generator 生成器函式一個包含yield關鍵字的函式就是一個生成器函式。yield可以為我們從函式中返回值,但是yield又不同於return,return的執行意味著程式的結束,呼叫生成器函式不會得到返回的具體的值,而是得到一個可迭代的物件。每一次獲取這個可
列表推導式+lambda+for(Python)
以下程式碼將輸出什麼?def testFun(): temp = [lambda x : i*x for i in range(4)] return temp for everyLambda in testFun(): print (everyLam
day012生成器函式、生成器表示式、列表推導式
本節主要內容 生成器和生成器表示式 列表推導式 一、生成器 生成器實質就是迭代器 1、python中獲取生成器的三種方式: * 通過生成器函式 * 通過生成器表示式 * 通過資料的轉換獲取生成器 1.生成器函式 **fe1:**
列表推導式,生成器表示式
示例:使用for迴圈從1列印到100的數 l1 = [] for i in range(1,101): l1.append(i) print(l1) 1、列表推導式 # 凡是用列表推導式能構建的資料,# python程式碼都可以構建,列表推導式不能構建的資料,python程式碼亦可以可
python3:列表推導式,生成器表示式,字典推導式 三種用法講解
列表推導式 任務: 我們有個任務是提取0—20的奇數位. 1.首先我們想到的是用for迴圈加if做到,如下: b=[] for i in range(21): if i%2==1: b.append(i) print(b) 2.懂list 也可以想
python day12 ——1.生成器2.生成器表示式 3.列表推導式
一、生成器 什麼是生成器. 生成器實質就是迭代器。 在python中有三種方式來獲取生成器: 1. 通過生成器函式。 2. 通過各種推導式來實現生成器 。 3. 通過資料的轉換也可以獲取生成器。 1.首先, 我們先看一個很簡單的函式:
列表推導式與lambda的結合
def fun(): # return (lambda x: x * i for i in range(4)) # 結果是[0,2,4,6] return [lambda x: x * i for i in range(4)]
生成器、列表推導式和生成器表示式
生成器 生成器特點: 1. 生成器本質上迭代器 2. 生成器是自己用程式碼建立的 獲取生成器的兩種方式: 1. 生成器函式 2. 生成器表示式 yield 下面來看一個例子 1 def func(): 2 print(111) 3 yield 66
python中:生成器表示式和列表推導式的比較
l = [2, 3, 5, 7] l2 = [x ** 2 + 1 for x in l] it = iter(l2) print(next(it)) # ? l[1] = 30 print
python列表推導式中使用if-else
python列表推導式 if-else 今天在處理自動化郵件數據時碰到數據行中包含字符串後,從hive中拿到的整數型數據自動轉化成了浮點數,嚴重影響美觀性。因此想到了用列表推導式來做轉化,將其中的數字型數據全部轉化為整型,而字符型數據保留原樣。列表推導式總共有兩種形式:①[x for x in data
Python3的列表推導式
odin utf int pri 列表推導式 列表 python return python3 # -*- coding: utf-8 -*- li = [1,2,3,4,5,6,7,8,9]print ([x**2 for x in li]) print ([x**2 f
列表推導式
引用 spa for 循環 字符 元素 字符串 書寫 列表推導 color 1-100 的平方 [x * x for x in range(100)] 書寫習慣為從右至左 依次寫出range(100) 然後for 循環 然後x * x 然後放進List 生成字符串 ["T
python列表推導式
lai com expr 實際應用 http port ack ron dig python基礎——列表推導式 1 列表推導式定義 列表推導式能非常簡潔的構造一個新列表:只用一條簡潔的表達式即可對得到的元素進行轉換變形 2 列表推導式語法 基本格式如下:
day4-列表推導式與生成器表達式
圖片 表達 class bsp 技術 com 列表推導 png src 用列表推導式變成一行: 列表解析: 列表解析最終生成的是一個真實存數據的列表。 2,生成器表達式: next一次執行一次。 day4-列表推導式與生成器表達式
六 三元表達式、列表推導式、生成器表達式
pan abc 一次 pri 聲明 優點 express 推導 next 一 三元表達式 二 列表推導式 三 生成器表達式 一 三元表達式 1 name=input(‘姓名>>: ‘) 2 res=‘abc‘ if name == ‘l
列表推導式----生成器表達式
odin 使用 結果 with open append split() spl eno enc 列表推導式: 基本形式: [表達式 for 參數 in 可叠代對象] 或者 [表達式 for 參數 in 可叠代對象 if 條件] 實例:
4-4日 列表推導式,生成器推導式
兩種模式 span 一個 列表 bsp 字符 ali eva pos 1,列表推導式就是在列表中進行for 循環if語句判斷,最多兩個for,一個if判斷 #求1到30 被3整除的數的平方 li = [i*i for i in range(1,31)if i%3 == 0
(列表推導式,生成器表達式,內置函數)
全局局部變量 通過 實例 app compile 根據 重要 字符編碼 初始 一,列表生成式 示例一: 生成1~100的列表 生成1~100的列表 1 2 3 4 5 li = [] for i in range(1,101): li.appen
三元表達式、列表推導式、生成器表達式、遞歸、內置函數、匿名函數
改變 現在 lose 知識庫 數據結構實現 結果 VM 情況 www. 一、三元表達式 name=input(‘姓名>>: ‘) res=‘SB‘ if name == ‘alex‘ else ‘NB‘ print(res) 二、列表推導式和生成器表達式