Python的函數(shù)(內(nèi)置函數(shù)和我們自己編寫的自定義函數(shù))是處理數(shù)據(jù)的關(guān)鍵工具。但是他們對(duì)數(shù)據(jù)的處理可能會(huì)有些混亂,如果我們不知道發(fā)生了什么,可能會(huì)導(dǎo)致分析中的嚴(yán)重錯(cuò)誤。
在python函數(shù)控制列表和詞典中,我們將仔細(xì)研究Python在函數(shù)內(nèi)部進(jìn)行操作時(shí)如何對(duì)待不同的數(shù)據(jù)類型,并學(xué)習(xí)如何確保僅在需要更改數(shù)據(jù)時(shí)才更改數(shù)據(jù)。
功能中的內(nèi)存隔離
要了解Python如何處理函數(shù)內(nèi)部的全局變量,讓我們做一些實(shí)驗(yàn)。我們將創(chuàng)建兩個(gè)全局變量number_1和number_2,并將它們分配給整數(shù)5and 10。然后,我們將這些全局變量用作執(zhí)行一些簡(jiǎn)單數(shù)學(xué)運(yùn)算的函數(shù)中的參數(shù)。我們還將變量名用作函數(shù)的參數(shù)名。然后,我們將查看函數(shù)內(nèi)部的所有變量用法是否已影響這些變量的全局值。
正如我們可以看到上面的功能工作正常,以及全球變量的值number_1,并number_2沒(méi)有不改變,即使我們用它們作為參數(shù),并在我們的函數(shù)的參數(shù)名稱。這是因?yàn)镻ython將函數(shù)的變量存儲(chǔ)在與全局變量不同的內(nèi)存位置中。它們是孤立的。因此,變量number_1在全局范圍內(nèi)可以具有一個(gè)值(5),而在函數(shù)內(nèi)部則可以具有不同的值(50),在此將其隔離。
列表和詞典呢?
清單
我們已經(jīng)看到,對(duì)number_1函數(shù)內(nèi)部的上述變量執(zhí)行的操作不會(huì)影響其全局值。但是number_1是一個(gè)整數(shù),這是一個(gè)非常基本的數(shù)據(jù)類型。如果我們嘗試使用不同的數(shù)據(jù)類型(例如列表)進(jìn)行相同的實(shí)驗(yàn),會(huì)發(fā)生什么?在下面,我們將創(chuàng)建一個(gè)名為的函數(shù)duplicate_last(),該函數(shù)將在我們將其作為參數(shù)傳遞的任何列表中復(fù)制最終條目。
如我們所見(jiàn),即使僅在函數(shù)中更改了全局值,此處的全局值也initial_list 已更新!
辭典
現(xiàn)在,讓我們編寫一個(gè)將字典作為參數(shù)的函數(shù),以查看在函數(shù)內(nèi)部對(duì)全局字典變量進(jìn)行修改時(shí)是否也會(huì)對(duì)其進(jìn)行修改。
為了使這一點(diǎn)更加現(xiàn)實(shí),我們將使用Python基礎(chǔ)知識(shí)課程中AppleStore.csv使用的數(shù)據(jù)集中的數(shù)據(jù)(可在此處下載數(shù)據(jù))。
在下面的代碼段中,我們從一個(gè)字典開(kāi)始,該字典包含數(shù)據(jù)集中每個(gè)年齡等級(jí)的應(yīng)用程序數(shù)量的計(jì)數(shù)(因此,有4,433個(gè)應(yīng)用程序的等級(jí)為“ 4 +”,987個(gè)應(yīng)用程序的等級(jí)為“ 9+”,等等。) 。假設(shè)我們要為每個(gè)年齡等級(jí)計(jì)算一個(gè)百分比,這樣我們就可以了解到哪個(gè)年齡等級(jí)在App Store中最常見(jiàn)。
為此,我們將編寫一個(gè)名為的函數(shù)make_percentages(),該函數(shù)將字典作為參數(shù)并將計(jì)數(shù)轉(zhuǎn)換為百分比。我們需要從零開(kāi)始計(jì)數(shù),然后對(duì)字典中的每個(gè)值進(jìn)行迭代,然后將它們添加到計(jì)數(shù)中,以便獲得評(píng)分的總數(shù)。然后,我們將再次遍歷字典,并對(duì)每個(gè)值進(jìn)行一些數(shù)學(xué)運(yùn)算以計(jì)算百分比。
在查看輸出之前,讓我們快速回顧一下上面發(fā)生的事情。在將應(yīng)用程序年齡分級(jí)的字典分配給變量后content_ratings,我們創(chuàng)建了一個(gè)名為的新函數(shù)make_percentages(),該函數(shù)帶有一個(gè)參數(shù):a_dictionary。
為了圖什么應(yīng)用程序的比例下降到每一個(gè)年齡分級(jí),我們需要知道應(yīng)用程序的總數(shù),所以我們先設(shè)置一個(gè)所謂的新的變量total,以0通過(guò)在每個(gè)鍵,然后循環(huán)a_dictionary,將它添加到total。
一旦完成,我們要做的就是a_dictionary再次循環(huán)遍歷,將每個(gè)條目除以總數(shù),然后將結(jié)果乘以100。這將為我們提供帶有百分比的字典。
但是,當(dāng)我們使用global content_ratings作為該新函數(shù)的參數(shù)時(shí)會(huì)發(fā)生什么呢?
就像我們?cè)诹斜碇锌吹降囊粯觕ontent_ratings,即使僅在make_percentages()我們創(chuàng)建的函數(shù)內(nèi)部對(duì)其進(jìn)行了修改,我們的全局變量也已更改。
那么,這里到底發(fā)生了什么?我們碰到了可變和不可變數(shù)據(jù)類型之間的差異。
可變和不可變數(shù)據(jù)類型
在Python中,數(shù)據(jù)類型可以是可變的(可變的)或不可變的(不變的)。盡管我們?cè)赑ython入門中使用的大多數(shù)數(shù)據(jù)類型都是不可變的(包括整數(shù),浮點(diǎn)數(shù),字符串,布爾值和元組),但列表和字典卻是可變的。這意味著全局列表或字典即使在函數(shù)內(nèi)部使用時(shí)也可以更改,就像我們?cè)谏厦娴氖纠锌吹降哪菢印?br />
要了解可變(可變)和不可變(不變)之間的區(qū)別,研究一下Python如何實(shí)際處理這些變量是有幫助的。
讓我們開(kāi)始考慮一個(gè)簡(jiǎn)單的變量賦值:
變量名的a作用類似于指向的指針5,它可以幫助我們5在需要時(shí)進(jìn)行檢索。
5是整數(shù),整數(shù)是不可變的數(shù)據(jù)類型。如果數(shù)據(jù)類型是不可變的,則意味著它一旦創(chuàng)建便無(wú)法更新。如果這樣做a += 1,我們實(shí)際上5并沒(méi)有更新到6。在下面的動(dòng)畫中,我們可以看到:
1)a最初指向5。
2)a += 1運(yùn)行,并將指針從5移到6,實(shí)際上并沒(méi)有改變number 5。
列表和字典等可變數(shù)據(jù)類型的行為有所不同。它們可以被更新。因此,例如,讓我們列出一個(gè)非常簡(jiǎn)單的列表:
如果將a附加3到此列表的末尾,我們不僅會(huì)指向list_1其他列表,還會(huì)直接更新現(xiàn)有列表:
即使我們創(chuàng)建了多個(gè)列表變量,只要它們指向同一個(gè)列表,更改該列表時(shí)它們也會(huì)全部更新,如下面的代碼所示:
這是上面代碼中實(shí)際發(fā)生的動(dòng)畫的可視化:
這解釋了為什么在我們較早地嘗試使用列表和字典時(shí)更改了全局變量的原因。由于列表和字典是可變的,因此更改它們(即使在函數(shù)內(nèi)部)也將更改列表或字典本身,而對(duì)于不可變的數(shù)據(jù)類型則不是這種情況。
保持可變數(shù)據(jù)類型不變
一般來(lái)說(shuō),我們不希望函數(shù)更改全局變量,即使它們包含諸如列表或字典之類的可變數(shù)據(jù)類型也是如此。那是因?yàn)樵诟鼜?fù)雜的分析和程序中,我們可能經(jīng)常使用許多不同的功能。如果所有人都在更改他們正在處理的列表和詞典,則很難跟蹤正在更改的內(nèi)容。
值得慶幸的是,有一個(gè)簡(jiǎn)單的方法可以解決此問(wèn)題:我們可以使用內(nèi)置的Python方法來(lái)復(fù)制列表或字典.copy()。
如果您尚未了解方法,請(qǐng)不要擔(dān)心。它們?cè)谖覀兊腜ython中級(jí)課程中已涉及到,但是對(duì)于本教程而言,您需要知道的是它的.copy()工作方式如下.append():
讓我們?cè)賮?lái)看一下我們?yōu)榱斜砭帉懙暮瘮?shù),并對(duì)其進(jìn)行更新,以使函數(shù)內(nèi)部發(fā)生的變化不會(huì)改變initial_list。我們需要做的就是將傳遞給函數(shù)的參數(shù)從initial_list更改為initial_list.copy()
如我們所見(jiàn),這解決了我們的問(wèn)題。原因如下:using .copy()創(chuàng)建列表的單獨(dú)副本,因此指向initial_list自身的a_list是新副本,而不是指向自身initial_list。a_list之后,對(duì)該單獨(dú)的列表(而不是列表initial_list本身)進(jìn)行的任何更改,因此的全局值initial_list不變。
但是,該解決方案仍然不是完美的,因?yàn)?copy()每次傳遞參數(shù)給函數(shù)時(shí),我們都必須記住要添加,否則就有可能意外更改的全局值initial_list。如果我們不想為此擔(dān)心,我們實(shí)際上可以在函數(shù)內(nèi)部創(chuàng)建該列表副本:
通過(guò)這種方法,我們可以像initial_list函數(shù)一樣安全地傳遞一個(gè)可變的全局變量,并且不會(huì)更改全局值,因?yàn)楹瘮?shù)本身會(huì)創(chuàng)建一個(gè)副本,然后對(duì)該副本執(zhí)行其操作。
該.copy()方法也適用于詞典。與列表一樣,我們可以簡(jiǎn)單地添加.copy()參數(shù)到傳遞函數(shù)的位置,以創(chuàng)建一個(gè)副本,該副本將用于該函數(shù),而無(wú)需更改原始變量:
但是,再次使用該方法意味著我們需要記住.copy() 每次將字典傳遞給make_percentages()函數(shù)時(shí)都要添加。如果我們要經(jīng)常使用此函數(shù),則最好將復(fù)制實(shí)現(xiàn)到函數(shù)本身中,這樣就不必記住這樣做了。
在下面,我們將.copy()在函數(shù)本身內(nèi)部使用。這將確保我們可以在不更改作為參數(shù)傳遞給它的全局變量的情況下使用它,并且無(wú)需記住要.copy()為傳遞的每個(gè)參數(shù)添加參數(shù)。
如我們所見(jiàn),修改函數(shù)以創(chuàng)建字典的副本,然后僅在該副本中將計(jì)數(shù)更改為百分比已使我們能夠執(zhí)行所需的操作,而無(wú)需實(shí)際更改content_ratings。
結(jié)論
在python函數(shù)控制列表和詞典中,我們研究了可變數(shù)據(jù)類型和可變數(shù)據(jù)類型之間的區(qū)別,可變數(shù)據(jù)類型可以更改,可變數(shù)據(jù)類型不能更改。我們了解了如何使用該方法.copy()制作可變數(shù)據(jù)類型(如列表和字典)的副本,以便我們可以在不更改其全局值的情況下在函數(shù)中使用它們。
填寫下面表單即可預(yù)約申請(qǐng)免費(fèi)試聽(tīng)!怕錢不夠?可先就業(yè)掙錢后再付學(xué)費(fèi)! 怕學(xué)不會(huì)?助教全程陪讀,隨時(shí)解惑!擔(dān)心就業(yè)?一地學(xué)習(xí),可推薦就業(yè)!
?2007-2022/ mwtacok.cn 北京漫動(dòng)者數(shù)字科技有限公司 備案號(hào): 京ICP備12034770號(hào) 監(jiān)督電話:010-53672995 郵箱:bjaaa@aaaedu.cc