Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
return語(yǔ)句用于終止一個(gè)函數(shù)的執(zhí)行,同時(shí)將一個(gè)返回值返回給這個(gè)函數(shù)的調(diào)用者。因此,return語(yǔ)句必須要被包含在函數(shù)之中;否則,程序就會(huì)出錯(cuò)。如果沒有為return語(yǔ)句指明它的返回值,那么它就默認(rèn)返回undefined。
如果一個(gè)函數(shù)中沒有顯式的寫明return語(yǔ)句,那么在函數(shù)執(zhí)行時(shí)JavaScript會(huì)在該函數(shù)執(zhí)行流程的末尾自動(dòng)添加一條未指明返回值的return語(yǔ)句。return語(yǔ)句也可以被添加在函數(shù)的前面部分,這通常用于當(dāng)滿足某個(gè)條件時(shí)而提前退出函數(shù)。
return語(yǔ)句的語(yǔ)法結(jié)構(gòu)如下所示:
return [expression];
其中expression可以是JavaScript中任意合法的表達(dá)式,它的計(jì)算結(jié)果就是return語(yǔ)句的返回值,在函數(shù)終止的時(shí)候會(huì)被返回給該函數(shù)的調(diào)用者。如果省略了expression,那么return語(yǔ)句的返回值就默認(rèn)為undefined。
如果要顯式指明expression,那么它和return關(guān)鍵字必須寫在同一行上,即它們之間不能有換行符。否則,JavaScript會(huì)自動(dòng)在return關(guān)鍵字的后面添加分號(hào)。此時(shí),該return語(yǔ)句其實(shí)是一個(gè)未指明返回值的return語(yǔ)句,而expression在return語(yǔ)句之后永遠(yuǎn)都不會(huì)被執(zhí)行到。
<script>
// 定義一個(gè)函數(shù),計(jì)算一個(gè)數(shù)的兩倍
function twice(x) {
var result = x * 2;
return result;
}
// 調(diào)用該函數(shù),并打印返回值
var value1 = twice(9);
console.log("value1 = " + value1);
</script>
以上代碼的執(zhí)行結(jié)果如下圖所示。我們用實(shí)參9調(diào)用函數(shù)twice(),它先計(jì)算9的兩倍然后再返回該結(jié)果,隨后該返回值被賦值給了變量value1。第10行的代碼打印出value1的值,可以看到它的值確實(shí)為18。
該示例中的twice()函數(shù)還可以簡(jiǎn)寫為下面的形式,即計(jì)算兩倍的表達(dá)式被包含在return語(yǔ)句中,它的結(jié)果被直接返回。這樣就不需要先聲明一個(gè)變量臨時(shí)保存計(jì)算結(jié)果,再用return語(yǔ)句返回該變量。
<script>
// 和上面代碼中的twice函數(shù)完全等價(jià)
function twice(x) {
return x * 2;
}
</script>
<script>
// 定義一個(gè)函數(shù),它的最后是一條沒有指明返回值的return語(yǔ)句
function abc() {
console.log("執(zhí)行函數(shù)abc().");
return;
}
// 調(diào)用該函數(shù),并打印返回值
var value2 = abc();
console.log("value2 = " + value2);
</script>
從下圖的執(zhí)行結(jié)果中我們可以看到,首先打印出了字符串"執(zhí)行函數(shù)abc().",說(shuō)明函數(shù)abc()確實(shí)被執(zhí)行了。第10行的代碼打印出的變量value2的值為undefined,這正是return語(yǔ)句的默認(rèn)返回值。
<script>
// 定義一個(gè)函數(shù),它省略了return語(yǔ)句
function abc() {
console.log("執(zhí)行函數(shù)abc().");
}
// 調(diào)用該函數(shù),并打印返回值
var value3 = abc();
console.log("value3 = " + value3);
</script>
下圖中的執(zhí)行結(jié)果表明,該示例和上一個(gè)例子的執(zhí)行結(jié)果完全一致(除了變量被命名為value3之外)。該例子的成功執(zhí)行表明,當(dāng)一個(gè)函數(shù)的執(zhí)行流程的最后一條語(yǔ)句是沒有顯式指定返回值的return語(yǔ)句時(shí),該return語(yǔ)句可以被省略。
當(dāng)一個(gè)函數(shù)的執(zhí)行流程的最后缺少return語(yǔ)句的時(shí)候,JavaScript會(huì)自動(dòng)在該執(zhí)行流程的最后添加一條沒有返回值的return語(yǔ)句,當(dāng)然該函數(shù)的返回值就為undefined了。
<script>
// return 語(yǔ)句在函數(shù)之外:這會(huì)導(dǎo)致程序出錯(cuò)
return;
console.log("青石野草");
</script>
以上代碼的執(zhí)行結(jié)果如下圖所示,我們可以看到瀏覽器明確指出第3行的return語(yǔ)句是錯(cuò)誤的。
return語(yǔ)句不一定非要是函數(shù)的最后一條語(yǔ)句,它也可以處于函數(shù)的前面或中間,用于提前終止函數(shù)的執(zhí)行。示例代碼如下所示:
<script>
// 定義一個(gè)函數(shù),它計(jì)算一個(gè)數(shù)的相反數(shù);
// 當(dāng)參數(shù)為0時(shí),它會(huì)被提前終止
function opposite(x) {
if(x == 0) {
console.log("0的相反數(shù)是它自身。");
return 0;
}
console.log("不為0的數(shù)的相反數(shù)是它的負(fù)數(shù)。");
return -x;
}
// 調(diào)用函數(shù),并打印返回值
var value4 = opposite(0);
console.log("value4 = " + value4);
</script>
我們使用實(shí)參0調(diào)用函數(shù)opposite(),當(dāng)實(shí)參為0的時(shí)候,會(huì)執(zhí)行if語(yǔ)句中的代碼。它首先打印字符串"0的相反數(shù)是它自身。",然后遇到語(yǔ)句return 0;。這條return語(yǔ)句提前終止函數(shù)的執(zhí)行,并返回0。因此,if語(yǔ)句后面的那一條打印語(yǔ)句和return -x;均不會(huì)被執(zhí)行。下圖中的執(zhí)行結(jié)果正印證了這一執(zhí)行流程。
這個(gè)例子也說(shuō)明了一個(gè)函數(shù)可以包含多個(gè)return語(yǔ)句,用于根據(jù)不同的情況而退出函數(shù)。
<script>
// 定義一個(gè)函數(shù),它和第一個(gè)例子中的函數(shù)幾乎一樣;
// 只是原本的return語(yǔ)句被拆分成了兩行。
function twice(x) {
var result = x * 2;
return
result;
}
// 調(diào)用函數(shù),并打印返回值
var value5 = twice(9);
console.log("value5 = " + value5);
</script>
該示例的執(zhí)行結(jié)果如下圖所示,可以看到第11行打印出的變量value5的值為undefined,而不是我們?cè)酒谕臄?shù)字18。這是怎么回事呢?
這個(gè)示例和第一個(gè)例子唯一的不同就是我們把return語(yǔ)句拆成了兩行,return關(guān)鍵字和它的返回值result被寫在了不同的行上。在其它編程語(yǔ)言或者JavaScript的某些其它語(yǔ)句中,這樣的拆行不會(huì)對(duì)原程序有任何影響。
但JavaScript的return語(yǔ)句是個(gè)例外,在本文的開頭我們就說(shuō)過(guò)如果return關(guān)鍵字和它的返回值之間有換行符的話,JavaScript會(huì)自動(dòng)在return關(guān)鍵字之后插入一個(gè)分號(hào),此時(shí)該return語(yǔ)句的意義就和我們所期望的不同了。
這樣自動(dòng)插入分號(hào)的結(jié)果就會(huì)讓該示例中的twice()函數(shù)實(shí)際等同于下面的代碼。此時(shí)無(wú)論傳遞的參數(shù)是多少,return語(yǔ)句都會(huì)提前終止函數(shù)并默認(rèn)返回undefined,而變量result始終都不會(huì)被返回。
<script>
// 定義一個(gè)函數(shù),它和第一個(gè)例子中的函數(shù)幾乎一樣;
// 只是原本的return語(yǔ)句被拆分成了兩行。
function twice(x) {
var result = x * 2;
return; // 注意,這個(gè)分號(hào)是JavaScript自動(dòng)插入的;它改變了程序的語(yǔ)義。
result;
}
</script>
如果你真的想要將return語(yǔ)句寫在多行上,那么你可以將返回值用括號(hào)括起來(lái)。但請(qǐng)一定要注意,此時(shí)左括號(hào)也必須要和return關(guān)鍵字寫在同一行上,就像下面的代碼這樣:
<script>
/* 要將return語(yǔ)句寫在多行上,可以用括號(hào)將返回值括起來(lái);
* 但是,左括號(hào)也必須要和return關(guān)鍵字寫在同一行上。
*/
function twice(x) {
return (
x * 2
);
}
</script>
(完)
源: AI入門學(xué)習(xí)
作者:小伍哥
apply()堪稱Pandas中最好用的方法,其使用方式跟map()很像,主要傳入的主要參數(shù)都是接受輸入返回輸出。
但相較于昨天介紹的map()針對(duì)單列Series進(jìn)行處理,一條apply()語(yǔ)句可以對(duì)單列或多列進(jìn)行運(yùn)算,覆蓋非常多的使用場(chǎng)景。
參考上篇:Pandas中的寶藏函數(shù)-map
基本語(yǔ)法:
DataFrame.apply(func, axis=0, raw=False, result_type=None,
args=(), **kwargs)
參 數(shù):
func : function 應(yīng)用到每行或每列的函數(shù)。
axis :{0 or 'index', 1 or 'columns'}, default 0 函數(shù)應(yīng)用所沿著的軸。
0 or index : 在每一列上應(yīng)用函數(shù)。
1 or columns : 在每一行上應(yīng)用函數(shù)。
raw : bool, default False 確定行或列以Series還是ndarray對(duì)象傳遞。
False : 將每一行或每一列作為一個(gè)Series傳遞給函數(shù)。
True : 傳遞的函數(shù)將接收ndarray 對(duì)象。如果你只是應(yīng)用一個(gè) NumPy 還原函數(shù),這將獲得更好的性能。
result_type : {'expand', 'reduce', 'broadcast', None}, default None 只有在axis=1列時(shí)才會(huì)發(fā)揮作用。
expand : 列表式的結(jié)果將被轉(zhuǎn)化為列。
reduce : 如果可能的話,返回一個(gè)Series,而不是展開類似列表的結(jié)果。這與 expand 相反。
broadcast : 結(jié)果將被廣播到 DataFrame 的原始形狀,原始索引和列將被保留。
默認(rèn)行為(None)取決于應(yīng)用函數(shù)的返回值:類似列表的結(jié)果將作為這些結(jié)果的 Series 返回。但是,如果應(yīng)用函數(shù)返回一個(gè) Series ,這些結(jié)果將被擴(kuò)展為列。
args : tuple 除了數(shù)組/序列之外,要傳遞給函數(shù)的位置參數(shù)。
**kwds: 作為關(guān)鍵字參數(shù)傳遞給函數(shù)的附加關(guān)鍵字參數(shù)。
官方:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html
先構(gòu)造一個(gè)數(shù)據(jù)集
data = pd.DataFrame(
{"name":['Jack', 'Alice', 'Lily', 'Mshis', 'Gdli', 'Agosh', 'Filu', 'Mack', 'Lucy', 'Pony'],
"gender":['F', 'M', 'F', 'F', 'M', 'F', 'M', 'M', 'F', 'F'],
"age":[25, 34, 49, 42, 28, 23, 45, 21, 34, 29]}
)
data
name gender age
0 Jack F 25
1 Alice M 34
2 Lily F 49
3 Mshis F 42
4 Gdli M 28
5 Agosh F 23
6 Filu M 45
7 Mack M 21
8 Lucy F 34
9 Pony F 29
這里我們參照2.1向apply()中傳入lambda函數(shù):
data.gender.apply(lambda x:'女性' if x is 'F' else '男性')
0 女性
1 男性
2 女性
3 女性
4 男性
5 女性
6 男性
7 男性
8 女性
9 女性
可以看到這里實(shí)現(xiàn)了跟map()一樣的功能。
apply()最特別的地方在于其可以同時(shí)處理多列數(shù)據(jù),我們先來(lái)了解一下如何處理多列數(shù)據(jù)輸入單列數(shù)據(jù)輸出的情況。
譬如這里我們編寫一個(gè)使用到多列數(shù)據(jù)的函數(shù)用于拼成對(duì)于每一行描述性的話,并在apply()用lambda函數(shù)傳遞多個(gè)值進(jìn)編寫好的函數(shù)中
注意:當(dāng)調(diào)用DataFrame.apply()時(shí),apply()在串行過(guò)程中實(shí)際處理的是每一行數(shù)據(jù),而不是Series.apply()那樣每次處理單個(gè)值,在處理多個(gè)值時(shí)要給apply()添加參數(shù)axis=1
def fun_all(name, gender, age):
gender = '女性' if gender is 'F' else '男性'
return '有個(gè)名字叫{}的人,性別為{},年齡為{}。'.format(name, gender, age)
data.apply(lambda row:fun_all(row['name'],row['gender'],row['age']), axis = 1)
0 有個(gè)名字叫Jack的人,性別為女性,年齡為25。
1 有個(gè)名字叫Alice的人,性別為男性,年齡為34。
2 有個(gè)名字叫Lily的人,性別為女性,年齡為49。
3 有個(gè)名字叫Mshis的人,性別為女性,年齡為42。
4 有個(gè)名字叫Gdli的人,性別為男性,年齡為28。
5 有個(gè)名字叫Agosh的人,性別為女性,年齡為23。
6 有個(gè)名字叫Filu的人,性別為男性,年齡為45。
7 有個(gè)名字叫Mack的人,性別為男性,年齡為21。
8 有個(gè)名字叫Lucy的人,性別為女性,年齡為34。
9 有個(gè)名字叫Pony的人,性別為女性,年齡為29。
def intro(r):
#r代指dataframe中的任意行,是series類型數(shù)據(jù),擁有類似字典的使用方法。
return '大家好,我是{name},性別是{gender},今年{age}歲了!'.format(name=r['name'], gender=r['gender'],age=r['age'])
data.apply(intro, axis=1)
Out[81]:
0 大家好,我是Jack,性別是F,今年25歲了!
1 大家好,我是Alice,性別是M,今年34歲了!
2 大家好,我是Lily,性別是F,今年49歲了!
3 大家好,我是Mshis,性別是F,今年42歲了!
4 大家好,我是Gdli,性別是M,今年28歲了!
5 大家好,我是Agosh,性別是F,今年23歲了!
6 大家好,我是Filu,性別是M,今年45歲了!
7 大家好,我是Mack,性別是M,今年21歲了!
8 大家好,我是Lucy,性別是F,今年34歲了!
9 大家好,我是Pony,性別是F,今年29歲了!
dtype: object
#其實(shí)這樣寫也是可以的,更簡(jiǎn)單些
def intro(r):
return '大家好,我是{},性別是{},今年{}歲了!'.format(r['name'], r['gender'],r['age'])
data.apply(intro, axis=1)
有些時(shí)候我們利用apply()會(huì)遇到希望同時(shí)輸出多列數(shù)據(jù)的情況,在apply()中同時(shí)輸出多列時(shí)實(shí)際上返回的是一個(gè)Series,這個(gè)Series中每個(gè)元素是與apply()中傳入函數(shù)的返回值順序?qū)?yīng)的元組。
比如下面我們利用apply()來(lái)提取name列中的首字母和剩余部分字母:
data.apply(lambda row: (row['name'][0], row['name'][1:]), axis=1)
0 (J, ack)
1 (A, lice)
2 (L, ily)
3 (M, shis)
4 (G, dli)
5 (A, gosh)
6 (F, ilu)
7 (M, ack)
8 (L, ucy)
9 (P, ony)
可以看到,這里返回的是單列結(jié)果,每個(gè)元素是返回值組成的元組,這時(shí)若想直接得到各列分開的結(jié)果,需要用到zip(*zipped)來(lái)解開元組序列,從而得到分離的多列返回值:
a, b = zip(*data.apply(lambda row: (row['name'][0], row['name'][1:]), axis=1))
a
('J', 'A', 'L', 'M', 'G', 'A', 'F', 'M', 'L', 'P')
b
('ack', 'lice', 'ily', 'shis', 'dli', 'gosh', 'ilu', 'ack', 'ucy', 'ony')
我們知道apply()在運(yùn)算時(shí)實(shí)際上仍然是一行一行遍歷的方式,因此在計(jì)算量很大時(shí)如果有一個(gè)進(jìn)度條來(lái)監(jiān)視運(yùn)行進(jìn)度就很舒服。
tqdm:用于添加代碼進(jìn)度條的第三方庫(kù)
tqdm對(duì)pandas也是有著很好的支持。
我們可以使用progress_apply()代替apply(),并在運(yùn)行progress_apply()之前添加tqdm.tqdm.pandas(desc='')來(lái)啟動(dòng)對(duì)apply過(guò)程的監(jiān)視。
其中desc參數(shù)傳入對(duì)進(jìn)度進(jìn)行說(shuō)明的字符串,下面我們?cè)谏弦恍〔糠质纠幕A(chǔ)上進(jìn)行改造來(lái)添加進(jìn)度條功能:
from tqdm import tqdm
def fun_all(name, gender, age):
gender = '女性' if gender is 'F' else '男性'
return '有個(gè)名字叫{}的人,性別為{},年齡為{}。'.format(name, gender, age)
#啟動(dòng)對(duì)緊跟著的apply過(guò)程的監(jiān)視
from tqdm import tqdm
tqdm.pandas(desc='apply')
data.progress_apply(lambda row:fun_all(row['name'],row['gender'],
row['age']), axis = 1)
apply: 100%|██████████| 10/10 [00:00<00:00, 5011.71it/s]
0 有個(gè)名字叫Jack的人,性別為女性,年齡為25。
1 有個(gè)名字叫Alice的人,性別為男性,年齡為34。
2 有個(gè)名字叫Lily的人,性別為女性,年齡為49。
3 有個(gè)名字叫Mshis的人,性別為女性,年齡為42。
4 有個(gè)名字叫Gdli的人,性別為男性,年齡為28。
5 有個(gè)名字叫Agosh的人,性別為女性,年齡為23。
6 有個(gè)名字叫Filu的人,性別為男性,年齡為45。
7 有個(gè)名字叫Mack的人,性別為男性,年齡為21。
8 有個(gè)名字叫Lucy的人,性別為女性,年齡為34。
9 有個(gè)名字叫Pony的人,性別為女性,年齡為2
可以看到在jupyter lab中運(yùn)行程序的過(guò)程中,下方出現(xiàn)了監(jiān)視過(guò)程的進(jìn)度條,這樣就可以實(shí)時(shí)了解apply過(guò)程跑到什么地方了。
結(jié)合tqdm_notebook()給apply()過(guò)程添加美觀進(jìn)度條,熟悉tqdm的朋友都知道其針對(duì)jupyter notebook開發(fā)了ui更加美觀的tqdm_notebook()。而要想在jupyter notebook/jupyter lab平臺(tái)上為pandas的apply過(guò)程添加美觀進(jìn)度條,可以參照如下示例:
eturn 定義:
return 語(yǔ)句會(huì) 終止函數(shù)的執(zhí)行 并 返回函數(shù)的值。
注意這兩個(gè): 1.終止函數(shù)的執(zhí)行 2.返回函數(shù)的值
返回函數(shù)的值這里就不過(guò)多敘述了,就是 return 變量
先看下面的例子:
<!DOCTYPE html> <html> <head> <title>return測(cè)試</title> </head> <body> <a href="#"></a> <a onclick="fun1()">111</a> <a onclick="fun2()">222</a> <a onclick="fun3()">333</a> <a onclick="fun4()">444</a> <script type="text/javascript"> function fun1() { return ; console.log('111 這個(gè)不會(huì)執(zhí)行') } function fun2() { return false console.log('222 這個(gè)不會(huì)執(zhí)行') } function fun3() { return true console.log('333 這個(gè)不會(huì)執(zhí)行') } function fun4() { console.log('444 這個(gè)會(huì)執(zhí)行') } </script> </body> </html>
通過(guò)上面的例子 可以看出 return ; return false return true 在函數(shù)內(nèi)部都中斷了函數(shù)的執(zhí)行
接著看看 他們返回的結(jié)果是個(gè)啥 代碼如下:
function fun1() { return ; } function fun2() { return false } function fun3() { return true } console.log(fun1()) // undefined console.log(fun2()) // false console.log(fun3()) // true
返回的結(jié)果分別是 undefined false true 注:(undefine != false)
有個(gè)知識(shí)點(diǎn) : 表單提交的時(shí)候 如果函數(shù)返回 false 表單就不提交了 ,切記!
首先看看能提交的情況,代碼如下:
<!DOCTYPE html> <html> <head> <title>return測(cè)試</title> </head> <body> <form method="post" onsubmit="return submitFunction()"> <input type="text" name="nameId"> <button type="submit" id="submit">提交</button> </form> <script type="text/javascript"> function submitFunction () { return ; } </script> </body> </html>
效果如下: 右邊出現(xiàn)了請(qǐng)求(注意:表單請(qǐng)求會(huì)刷新頁(yè)面)
阻止表單提交的代碼如下:
<!DOCTYPE html> <html> <head> <title>return測(cè)試</title> </head> <body> <form method="post" onsubmit="return submitFunction()"> <input type="text" name="nameId"> <button type="submit" id="submit">提交</button> </form> <script type="text/javascript"> function submitFunction () { return false; } </script> </body> </html>
效果如下:右邊沒有出現(xiàn)請(qǐng)求,請(qǐng)求被阻止了
總結(jié)如下:
1. return ; return false return true 都會(huì)在函數(shù)內(nèi)部阻止程序的執(zhí)行。
2. 只有 return false 會(huì)阻止表單的提交。
對(duì)前端的技術(shù),架構(gòu)技術(shù)感興趣的同學(xué)關(guān)注我的頭條號(hào),并在后臺(tái)私信發(fā)送關(guān)鍵字:“前端”即可獲取免費(fèi)的架構(gòu)師學(xué)習(xí)資料
知識(shí)體系已整理好,歡迎免費(fèi)領(lǐng)取。還有面試視頻分享可以免費(fèi)獲取。關(guān)注我,可以獲得沒有的架構(gòu)經(jīng)驗(yàn)哦!!
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。