A级片三级毛片中文字幕|97人人干人人爱|aaaaa毛片亚洲av资源网|超碰97在线播放|日本一a级毛片欧美一区黄|日韩专区潮吹亚洲AV无码片|人人香蕉视频免费|中文字幕欧美激情极品|日本高清一级免费不卡|国模大胆在线国产啪视频

AQF
首頁(yè) 備考指南 精品課程 名師團(tuán)隊(duì) 職業(yè)前景
您現(xiàn)在的位置:首頁(yè)備考必備AQF資料 Python量化隨筆丨那些年,我寫(xiě)Python踩過(guò)的坑(一)

Python量化隨筆丨那些年,我寫(xiě)Python踩過(guò)的坑(一)

發(fā)表時(shí)間: 2019-03-14 10:19:51 編輯:tansy

這是一篇關(guān)于Python量化的筆記,記錄了Python隱藏的坑,以及我是如何發(fā)現(xiàn)如何避免的,希望你們?cè)趯W(xué)Python的路上能夠暢通無(wú)阻,不踩坑~

  這是一篇關(guān)于Python量化的筆記~坑的時(shí)候有一種很奇怪的感覺(jué),我對(duì)python似曾相識(shí),又覺(jué)得陌生。打游戲發(fā)現(xiàn)新的隱藏關(guān)卡帶來(lái)的是喜悅,而python的坑帶來(lái)的是自我懷疑,甚至可能是實(shí)實(shí)在在的經(jīng)濟(jì)損失,所以,坑,我們踩過(guò)的,一定帶你繞過(guò)去。

  下面讓我們一起看看python隱藏的坑,排名不分先后。 >>>點(diǎn)擊咨詢量化投資行業(yè)前景

  1. Python量化之基礎(chǔ)篇

  基礎(chǔ)的坑,最重要的是舉一反三,最怕的是在黑板上老師寫(xiě)了‘一’,回家在筆記本上寫(xiě)一個(gè)橫線就不認(rèn)識(shí)這種事情。

  忘記寫(xiě)冒號(hào)。在def,if,while,for等語(yǔ)句第一行某位輸入”:”。

  縮進(jìn)要一致。避免在縮進(jìn)時(shí)混合使用制表符和空格。

  不要認(rèn)為在原處修改對(duì)象的函數(shù)會(huì)返回結(jié)果。例如a = list.append(),a是不會(huì)被賦值的。

  不要在變量賦值前就使用變量。例如a = b寫(xiě)這行代碼時(shí),b在此之前一定要被賦值過(guò)的。

  函數(shù)調(diào)用一定要加括號(hào)。例如dataframe.dropna()。

  不要寫(xiě)死循環(huán)。例如while True: 之后的代碼塊中沒(méi)有跳出循環(huán)的代碼。

  判斷兩個(gè)變量是否相等用的是‘==’號(hào)。大多數(shù)初學(xué)者,覺(jué)得‘=’號(hào)就可以了。

  寫(xiě)字符串,寫(xiě)各種樣式的括號(hào)時(shí)注意他們是成對(duì)出現(xiàn)的。常見(jiàn)['a', b']這樣的錯(cuò)誤,然后覺(jué)得自己代碼沒(méi)有問(wèn)題的初學(xué)者。

  >>>點(diǎn)擊咨詢?nèi)绾蜗到y(tǒng)學(xué)習(xí)Python量化投資

  2. Python量化之進(jìn)階篇

  有一句歌詞唱的挺好的,“跨過(guò)這道山,越過(guò)那道嶺,眼前又是一座峰”?;A(chǔ)的坑排完了,還會(huì)有更多,更隱藏的坑等著你去踩。(比較熟悉這個(gè)歌的同學(xué),我覺(jué)得你大概率上是北方人,更具體點(diǎn)的話,是東北人)

  2.1 賦值僅僅生成引用

  a = [1, 2, 3]

  b = a

  這里你認(rèn)為自己構(gòu)建了兩個(gè)相同的列表,準(zhǔn)備用在不同的用途。然而當(dāng)開(kāi)開(kāi)心心的進(jìn)行接下來(lái)的其他操作時(shí),比如,對(duì)a進(jìn)行修改,就發(fā)生了其他的事情。

  a[1] = 100000a

  out: [1, 100000, 3]

  b

  out: [1, 100000, 3]

  結(jié)果發(fā)現(xiàn),本來(lái)希望只對(duì)a進(jìn)行修改,結(jié)果發(fā)現(xiàn)b也受到了影響,其原因在于通過(guò)b = a的方式進(jìn)行對(duì)b賦值,其實(shí)a、b指向同一個(gè)列表對(duì)象。我們可以通過(guò)查看a、b的內(nèi)存地址或用is進(jìn)行驗(yàn)證

  print(id(a), id(b))

  out: 124006856 124006856

  可以看到a、b指向的其實(shí)是同一塊內(nèi)存

  a is b

  out: True

  用is也檢測(cè)出a和b完全就是一個(gè)東西的不同名字而已。

  上面的賦值方法還是比較容易看出,因?yàn)橛械忍?hào),那么下面的賦值方法可能就稍微難一點(diǎn)看出來(lái)了。

  c = [1, a, 3]

  c

  out: [1, [1, 100000, 3], 3]

  當(dāng)對(duì)a修改時(shí),c同樣也會(huì)受到影響

  a.append(100000)

  a

  out: [1, 100000, 3, 100000]

  c

  out: [1, [1, 100000, 3, 100000], 3]

  所以,不要覺(jué)得寫(xiě)完了,print出來(lái)的東西看著和自己想的一樣就萬(wàn)事大吉,不實(shí)際踩一下肯定不知道接下來(lái)有坑。

  那么,如何解決呢?用 .copy(),這樣就會(huì)產(chǎn)生兩個(gè)不相干的對(duì)象,當(dāng)然如果不嫌麻煩的話,可以把相同的東西再打一遍,然后,你有沒(méi)有看到同行鄙視的眼神?

  我們看一下效果。

  a = [1, 2, 3]

  b = a.copy()

  a is b

  out: False

  print(id(a), id(b))

  out:125323528 87389000

  可以看到a,b指向了不同的內(nèi)存地址,并且用is檢測(cè)顯示是不同對(duì)象。

  接下來(lái)修改a。

  a[1] = 100000a

  out: [1, 100000, 3]

  b

  out: [1, 2, 3]

  可以看到修改a已經(jīng)不會(huì)對(duì)b產(chǎn)生影響了,此坑已填。

  2.2 乘法與嵌套列表

  編程的某個(gè)時(shí)候,你希望生成這樣一個(gè)嵌套列表[[],[],[],..., [],[]],里面的列表為空或者默認(rèn)值,那么第一選擇肯定是利用列表乘法一次性生成多個(gè)列表,像這樣

  a = [[]] * 5a

  out: [[], [], [], [], []]

  確實(shí)滿足了需求,然后當(dāng)你開(kāi)開(kāi)心心的使用時(shí),發(fā)覺(jué)事情有點(diǎn)不太對(duì)。比如對(duì)a列表中作為元素的某一個(gè)列表進(jìn)行修改

  a[0].append(1000)

  a[0]

  out: [1000]

  a

  out: [[1000], [1000], [1000], [1000], [1000]]

  然后發(fā)現(xiàn),怎么所有作為元素的列表全都發(fā)生了變化。這次同樣可以用id或這is進(jìn)行檢測(cè)。

  print(id(a[0]), id(a[1]))

  out: 125325256 125325256

  a[0] is a[1]

  out: True

  可以看出,原來(lái)a列表中作為元素的每一個(gè)列表,其實(shí)都是同一個(gè)東西,這也就解釋了為什么對(duì)其中一個(gè)作為元素的列表進(jìn)行原地修改時(shí),其他所有作為元素的列表也發(fā)生了變化。

  那么,解決方案如下

  a = [[] for i in range(5)]

  a

  out: [[], [], [], [], []]

  a[0] is a[1]

  out: False

  print(id(a[0]), id(a[1]))

  out: 125323144 125321544

  可以看到,a中作為元素的列表已經(jīng)不是同一個(gè)了,這樣對(duì)其中的列表進(jìn)行修改時(shí)候就不會(huì)影響其他列表。

  a[0].append(1000)

  a

  out: [[1000], [], [], [], []]

  此坑已填

  2.3 本地變量靜態(tài)檢測(cè)

  剛剛了解作用域的同學(xué)應(yīng)該對(duì)LEGB原則有一定了解,然后實(shí)踐中可能大膽的寫(xiě)出了這樣的函數(shù)。

  a = 1def print_a():

  print(a)

  a = 2

  這個(gè)函數(shù)的目的也比較容易理解,打印a的值之后將a的值修改為2,但是,實(shí)際運(yùn)行時(shí)發(fā)生了這樣的事情。

  print_a()

  ---------------------------------------------------------------------------

  out: UnboundLocalError Traceback (most recent call last)

   in ()

  ----> 1 print_a()

   in print_a()

  1 a = 1

  2 def print_a():

  ----> 3 print(a)

  4 a = 2

  UnboundLocalError: local variable 'a' referenced before assignment

  發(fā)生這樣問(wèn)題的原因是在python讀入并編譯這段代碼時(shí),發(fā)現(xiàn)def里面有一個(gè)對(duì)a賦值的語(yǔ)句,然后決定a在函數(shù)中屬于本地變量名。那么當(dāng)print_a執(zhí)行時(shí),就會(huì)對(duì)print(a)按照LEGB原則執(zhí)行搜索,發(fā)現(xiàn)a屬于本地變量名但還未賦值。也就是我們?cè)谇懊婊A(chǔ)坑里面提到的在變量未賦值前進(jìn)行使用。

  解決方案需要使用global聲明a是一個(gè)全局變量。

  a = 1def print_a():

  global a

  print(a)

  a = 2

  print_a()

  out: 1

  a

  out: 2

  可以看到,函數(shù)已經(jīng)可以正常使用,并且全局變量a按照預(yù)期進(jìn)行了修改。此坑已填。

  2.4 可變對(duì)象作函數(shù)默認(rèn)參數(shù)

  默認(rèn)參數(shù)在def語(yǔ)句運(yùn)行時(shí)完成了保存,對(duì)于可變對(duì)象而言,當(dāng)函數(shù)被調(diào)用并對(duì)該參數(shù)進(jìn)行原地修改,默認(rèn)參數(shù)將發(fā)生變化并進(jìn)而影響接下來(lái)的函數(shù)調(diào)用。

  先用可變對(duì)象作為默認(rèn)參數(shù)編寫(xiě)一個(gè)函數(shù)。

  def test(a=[]):

  a.append(1)

  print(a)

  接下來(lái)多次調(diào)用test函數(shù),你一定以為每次打出來(lái)的都是一個(gè)包含1的列表。但是,事實(shí)并不是這樣。

  test()

  out: [1]

  test()

  out: [1, 1]

  test()

  out: [1, 1, 1]

  是不是感覺(jué)三觀盡毀啊。

  當(dāng)然,有坑就會(huì)有填坑的方案。官方給出的標(biāo)準(zhǔn)解決方案是這樣的。

  def test(a=None):

  if a is None:

  a = []

  a.append(1)

  print(a)

  test()

  out: [1]

  test()

  out: [1]

  可以看到,test多次被調(diào)用已經(jīng)不會(huì)出現(xiàn)之前的情況了。此坑已填。

  2.5 嵌套在循環(huán)中的lambda

  在知道python中一切皆對(duì)象之后,也許你就會(huì)嘗試把一些特別的東西放進(jìn)一個(gè)list,雖然不清楚未來(lái)實(shí)際會(huì)不會(huì)用到這樣的寫(xiě)法,反正先試試。然后你就想將一套簡(jiǎn)單的函數(shù)放進(jìn)一個(gè)列表,然后用lambda編寫(xiě)。

  func_list = []for i in range(5):

  func_list.append(lambda x: x + i)

  這樣生成了一個(gè)元素為函數(shù)的列表,其中每個(gè)函數(shù)都可以傳入一個(gè)參數(shù),然后返回的是傳入值和0,1,2,3,4的和。當(dāng)然理想情況下是這樣,現(xiàn)實(shí)并不會(huì)如此。

  func_list[0](1)

  out: 5

  func_list[1](1)

  out: 5

  func_list[2](1)

  out: 5

  可以發(fā)現(xiàn),所有結(jié)果都是4+1的和。發(fā)生這種現(xiàn)象的原因在于變量i在函數(shù)調(diào)用時(shí)才進(jìn)行查找,而此時(shí)循環(huán)已經(jīng)結(jié)束,i=4,所以所有函數(shù)對(duì)象在被調(diào)用時(shí)參數(shù)i全部都為5.

  那么解決方案就是按照本文2.4中寫(xiě)的,默認(rèn)參數(shù)在def語(yǔ)句運(yùn)行時(shí)完成了保存,也就是使用默認(rèn)參數(shù)的方式解決該問(wèn)題。

  func_list = []for i in range(5):

  func_list.append(lambda x, i=i: x + i)

  func_list[0](1)

  out: 1

  func_list[1](1)

  out: 2

  func_list[2](1)

  out: 3

  可以看到,問(wèn)題已經(jīng)得到解決。此坑已填。

  2.6 列表和enumerate

  熟悉列表,學(xué)習(xí)python算是入門(mén);熟悉enumerate,學(xué)習(xí)python可以說(shuō)不是純小白了。enumerate返回下標(biāo)和元素的方式還是為python使用者提供了不大不小的便利,不過(guò)同時(shí)也挖下了一個(gè)坑。

  比如你寫(xiě)了一個(gè)循環(huán),想從列表中刪除偶數(shù)。

  a = [1,2,3,4,5,6]for i, item in enumerate(a): if a[i] % 2==0: del a[i]

  a

  out: [1, 3, 5]

  是不是想說(shuō)沒(méi)什么錯(cuò)誤啊,然后在給你看看這個(gè)。

  a = [1,2,6,3,4,4]for i, item in enumerate(a): if a[i] % 2==0: del a[i]

  a

  out: [1, 6, 3, 4]

  enumerate(a)

  out:

  產(chǎn)生這個(gè)問(wèn)題的原因是在當(dāng)i=1時(shí),a[1]的值為2,符合條件,那么刪除2這個(gè)值之后,a整個(gè)列表發(fā)生了變化,6這個(gè)數(shù)值前進(jìn)一個(gè)位置到了a[1]的位置,然后i在執(zhí)行下一次循環(huán)時(shí)候值取了2,我們以為應(yīng)該對(duì)應(yīng)著檢驗(yàn)6,其實(shí)6被前移一個(gè)位置,也就被遺漏了。

  下面我們將for 循環(huán)的部分手動(dòng)執(zhí)行,看現(xiàn)實(shí)是不是和我們理解的一樣。

  a = [1,2,6,3,4,4]

  e = enumerate(a)

  e

  out:

  i, item = e.__next__()

  (i, item)

  out: (0, 1)

  if a[i] % 2==0: del a[i]

  a

  out: [1, 2, 6, 3, 4, 4]

  此時(shí)我們可以看到,執(zhí)行完循環(huán)的第一步,a并沒(méi)有發(fā)生變化。接下來(lái)我們繼續(xù)第二步。

  i, item = e.__next__()

  (i, item)

  out: (1, 2)

  if a[i] % 2==0: del a[i]

  a

  out: [1, 6, 3, 4, 4]

  可以發(fā)現(xiàn),a已經(jīng)發(fā)生了變化,那么我們接下來(lái)只要看在enumerate提供新的下標(biāo)好元素是不是還按照未調(diào)整的a進(jìn)行提供的。當(dāng)然,可以告訴你們答案,肯定不是了。

  i, item = e.__next__()

  (i, item)

  out: (2, 3)

  可以看到6已經(jīng)不是第三個(gè)元素, 它通過(guò)向前移動(dòng)一個(gè)位置的方式逃過(guò)了檢查。這個(gè)坑真的是非常難發(fā)現(xiàn),因?yàn)橛袝r(shí)候碰巧你的運(yùn)算方式和提供的列表剛剛好結(jié)果是你想要的,然后讓你覺(jué)得這樣用就是正確的。這種時(shí)候就非??膳铝恕?/p>

  這個(gè)坑的解決方案可以使用列表解析式添加篩選條件即可。

  a = [1, 2, 6, 3, 4, 4]

  a = [x for x in a if x%2 != 0]

  a

  [1, 3]

  此坑已填。

  是不是覺(jué)得覺(jué)得一不留神就掉進(jìn)Python的坑里了?哈哈哈,寫(xiě)到這里,python編程一些比較基礎(chǔ)的坑也已經(jīng)描述的比較詳細(xì)了。我從來(lái)不產(chǎn)生失落感,我只是信心的粉碎機(jī)。當(dāng)你覺(jué)得自己python已經(jīng)學(xué)的差不多的時(shí)候,總會(huì)有那么一個(gè)人、或者一篇文章告訴你,你懂得還不夠多。如果你想學(xué)習(xí)Python量化培訓(xùn)相關(guān)的內(nèi)容的話,歡迎閱讀這篇文章:求推薦!上海Python量化培訓(xùn)班哪家比較好?

  不過(guò),坑總是有的,學(xué)習(xí)的時(shí)候你可以抱著填坑的心態(tài),也可以懷著獲取的目的,兩者都取決于你的選擇。而且,個(gè)人覺(jué)的,懷著獲取的態(tài)度,容易滿足,不斷追求,也就一直快樂(lè)。

  最后,還是用毒翼神龍的一段話結(jié)個(gè)尾:“幾盤(pán)卡帶就可以陪我們走過(guò)整個(gè)童年的那個(gè)時(shí)代恐怕也一去不復(fù)返了吧。每天的生活被工作、學(xué)習(xí)、應(yīng)酬充斥著,也讓我們漸漸忘記了那個(gè)傳說(shuō)~雖然它是一段美麗的謠言,但想起那個(gè)信以為真的年紀(jì),仍然有許多美好的回憶。我懷念那時(shí)單純的快樂(lè),懷念那個(gè)很容易就能滿足的童心”

AQF在線咨詢

  金程推薦: AQF就業(yè)前景 AQF年薪 量化金融分析師年薪

  AQF考友群:760229148

  金融寬客交流群:801860357

  微信公眾號(hào):量化金融分析師

  >>>返回首頁(yè)

吐槽

對(duì)不起!讓你吐槽了

/500

上傳圖片

    可上傳3張圖片

    2001-2025 上海金程教育科技有限公司 All Rights Reserved. 信息系統(tǒng)安全等級(jí):三級(jí)
    中央網(wǎng)信辦舉報(bào)中心 上海市互聯(lián)網(wǎng)舉報(bào)中心 不良信息舉報(bào)郵箱:law@gfedu.net
    滬ICP備14042082號(hào) 滬B2-20240743 通過(guò)ISO9001:2015 國(guó)際質(zhì)量管理體系認(rèn)證 滬公網(wǎng)安備31010902103762號(hào) 出版物經(jīng)營(yíng)許可證 電子營(yíng)業(yè)執(zhí)照

    掃描二維碼登錄金程網(wǎng)校

    請(qǐng)使用新版 金程網(wǎng)校APP 掃碼完成登錄

    登錄即同意金程網(wǎng)校協(xié)議及《隱私政策》