python實現鏈表的刪除_Python中 為我們提供了一些獨特的解決方案的方法特性

實際上,在日常的工作中,我們很多需求,無論是常見的、還是不常見的,Python 都為我們提供了一些獨特的解決方案,既不需要自己造輪子,也不需要引入新的依賴(引入新的依賴勢必會增加項目的復雜度)。

但是 Python 有太多功能和特性被我們忽略了,導致我們在遇到問題的時候,沒法第一時間作出良好的決策。

50aff9ee0eea7eca83483043a7478438.png

所以,干脆來一起掃清這些被我們忽略的 Python 死角。

裝飾器的妙用

我們經常會想完成一些注冊&調用的功能,比如我們有四個函數:

afe9d58d2dcdb3c3d9803b751627a881.png

現在我們想將這四個函數和 +、-、*、/ 四個操作符綁定,那么我們該怎么做?

可能我們第一反應是這樣:

3261c62dc6c01d3dd097c767c530aafc.png

但這樣寫起來,有一個很大的問題就是太不美觀了。因為直接對于 dict 的操作從實際上來講可維護性是很差的,那么我們這個地方應該怎么做?

在改進這段代碼之前,我們首先要明確 Python 中一個很重要的概念,即:函數/方法是:First Class Member 。用不精確的話來講,就是函數/方法可以作為參數被傳遞、被使用。

舉個例子:

3f28bd7d64775e7fdd7d5f661a2cabda.png

大家可以看到我們將 print_func 這個函數作為參數傳遞給 execute 函數并被調用。

那么我們來改造下之前的代碼:

29ec7226de82b5cd0192bd25b8436343.png

好了,大家看看,目前整體代碼的可讀性以及可維護性是不是改了很多?

但是我們現在的問題在于,每次都需要在單獨調用一次 register_operator 函數,這樣也太煩了吧!要不要再改進一下?要得。我們可以用裝飾器來改進一下。

首先,看一個最簡單的裝飾器例子:

a908c0a7b328faed8882474c57386646.png

我們能看到這段函數的意義是計算函數的執行時間。那么這個原理是什么?

實際上裝飾器是一個語法糖,具體可以參見 PEP318 Decorators for Functions and Methods。

簡而言之,實際上是 Python 替我們做了一個替換過程。以上面的例子為例,這個替換過程就是 add=execute(add) 。

好了,我們就用這個知識點來改進下之前的代碼:

db56eae96ee1a7eb96b158b4efe29c91.png

這樣我們這段代碼的注冊過程是不是就顯得更優雅了?

嗯,是的!實際上 Python 中有很多特性會幫助我們的代碼更簡潔,更優美。

接下來這個例子很可能幫我們減輕工作量。

聊聊 OrderedDict

dict 是我們經常使用的一種數據解構。但是在 Python 3.6 之前 dict 都是無序的,即我插入的順序,和數據在 dict 中存放的順序并無關聯(筆者注:Python 3.6 dict 有序只是新版實現的順帶產物,Python 3.7 正式作為 feature 被固定下來)。

但是很多時候,比如在驗簽等場景,我們需要保證 dict 數據存放順序,和我們插入順序是一致的。那么我們該怎么辦?

老板有需求下來了,我們肯定不能告訴老板這個需求沒法做。那我們就自己實現一個 ordereddict 吧。于是,想了想,寫了如下的代碼:

7c1780587b815e5a78d98d9462dd75a2.png

通過額外維護一個 list 來維護 key 插入的順序。這段代碼,看似完成了我們的需求,但是實則存在很大問題。大家可以猜猜問題在哪?

3,2,1!

揭曉答案,這段代碼利用 list 來保證 key 的有序性,在刪除的時候, list 的刪除操作,是一個時間復雜度 O(n) 的操作。換句話說,我們的刪除操作隨著內部數據的增多,所需的刪除時間也變得越長。這對于某些性能敏感的場景是無法接受的。

那要怎么辦呢?事實上,Python 在很早之前就已經內置了有序字典,即很多人可能都用過的 collections.OrderedDict 。

在 OrderedDict 中, Python 維護了一個雙向鏈表解構,來保證插入的有序性,如下圖所示:

69cb3d26c431d2977dc1cfbf3572fc8f.png

在最左側維護一個衛兵節點,衛兵節點的 next 指針恒指向于數據中最后插入的節點。那么插入新的數據時,我們將新的數據插入到衛兵節點之后,從而達成維護插入順序的目的。

在刪除的時候,通過額外維護的一個字典找到待刪除的 key 所對應的節點。這個操作是 O(1) 的復雜度,然后大家都知道,雙向鏈表刪除一個節點的時間復雜度也是 O(1) 。通過這樣保證我們在即便有大量數據的情況下,也能保證相應的性能。

好了,我們按照這個思路來做一個最簡單的實現:

d7df235483612bfc766af43ae7e262e3.png

這只是一個 OrderedDict 的簡化版,如果想完成一個完整的 OrderedDict 還有很多很多的 corner case 要去處理。不過現在,我們可以使用內置的數據結構去完成我們需求。怎么樣,是不是有了一種幸福的感覺?

喜歡小編文章的可以點個贊關注小編哦,小編每天都會給大家更新文章。

我自己是一名從事了多年的Python老程序員,小編為大家準備了新出的python編程學習資料,免費分享給大家!

如果你也想學習Python,那么幫忙轉發一下然后再關注小編后私信“01”可以得到我整理的這些Python資料了(私信方法:點擊我頭像進我主頁有個上面有個私信按鈕)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537607.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537607.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537607.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

打通C/4HANA和S/4HANA的一個原型開發:智能服務創新案例

2019獨角獸企業重金招聘Python工程師標準>>> 今年6月SAP發布C/4HANA之后,有顧問朋友們在公眾號后臺留言,詢問C/4HANA如何同SAP的數字化核心S/4HANA系統結合起來,從而打通企業的前后端業務,幫助企業實現數字化轉型。 有…

爬蟲的重要思想

1.理論上講只要網頁上面能夠看到的數據都是可以爬取的,因為所有看到的網頁上的數據都是服務器發送到我們電腦上面的,只是有的數據加密過,很難解密。 2.在網頁上無法看到或者無法獲取的數據,爬蟲同樣不可能拿到,比如一…

python web環境傻瓜搭建_python——web 環境搭建

1.安裝引用第三方庫 selenium pip install selenium 2.下載瀏覽器驅動(驅動版本和瀏覽器版本要對應參考鏈接 http://npm.taobao.org/mirrors/chromedriver/) 查看瀏覽器驅動對應關系,本次已最新驅動版本作為教材講解 版本2.42 發布時間2018.9…

項目管理十大知識領域,為何不含

問:項目管理十大知識領域,為何不含以下幾項:立項管理,合同管理,文檔管理,變更管理? 答: 立項完了才有項目; 合同管理包含在采購管理; 變更管理在整體管理&am…

B站視頻下載(VideoHelper)

繼續上次的知乎爬蟲, 這次開始了嗶哩嗶哩的爬蟲實踐; 首先介紹下如何下載吧: VideoHelper 里面有三種方式下載b站視頻。 同樣的流程, 還是先抓包,分析參數,尋找參數(包括之前的請求包和頁面源碼…

在職場遇到一個總是說話帶刺的同事怎么相處?

網友: 帶刺的人如果總是撲空,或者總是戳進一團棉花,你說他,她還能堅持多久。職場重心是工作,是做事,不要為這些無聊的人事太費心,刺猬帶著刺到處轉,最后結果不會好的。 網友&#xf…

postgresql 怎么讀_大數據采集和抽取怎么做?這篇文章終于說明白了!

本文來源于公眾號【胖滾豬學編程】,轉載請注明出處! 關于數據中臺的概念和架構,我們在大白話 六問數據中臺和數據中臺全景架構及模塊解析!一文入門中臺架構師!兩篇文章中都說明白了。從這一篇文章開始分享中臺落地實戰…

ZooKeeper應用——解決分布式系統單點故障

1.單點故障問題什么是分布式系統中的單點故障:通常分布式系統采用主從模式,就是一個主控機連接多個處理節點。主節點負責分發任務,從節點負責處理任務,當我們的主節點發生故障時,那么整個系統就都癱瘓了,那…

老板思維:有支出必須有對應的收入

項目經理 要時刻關注“有支出必須有對應的收入”。 當手頭的項目產生支出時,必須要問自己,從哪里收入來填補這個支出,如果沒有可收入的,那就是公司虧錢了。如果一定要虧錢,那可否產生收入之外的效益。 甲方提了新需求…

生活之難:生活到底難在哪里

生活之難:生活到底難在哪里 一、總結 一句話總結:難在天性,難在競爭,難在積累,難在追求,難在自己 難在天性 人的天性就是好吃懶做好玩不動腦的,但是生存的壓力(食物,房子…

解決org.springframework.web.multipart.MaxUploadSizeExceededException報錯問題

在springboot中接收到上傳的文件時候,出現了這種錯誤 org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.Fil…

python中元祖 字典 列表的區別_Python中元祖,列表,字典的區別

原博文 2016-08-16 15:25 ? Python中有3種內建的數據結構:列表、元祖和字典: 1.列表 list是處理一組有序項目的數據結構,即你可以在一個列表中存儲一個序列的項目。 列表中的項目應該包括在方括號中,這樣Python就知道你是指明一個…

react 16.6 懶加載 Lazy 嘗鮮

react 16.6 發布了新的功能 lazy ,和一個組件 Suspense 下面我們看一下他的用法 首先我們先創建兩個組件 LazyTest.1 和 LazyTest.2,內容相同 import React, { Component } from reactexport default class LazyTest extends Component{render(){return …

Intellij IDEA展示類中的方法樹形結構

在intellij Idea中叫Structure(結構體),如下圖; 也可以直接AltF7快捷鍵,這樣默認會把Structure顯示在屏幕下方,如下圖操作就可以移動到右側。 效果如下:

時間計算題100道_2019四校及分校自招開放日情況匯總(含時間安排、考試內容難度、到場人數等)...

點擊上方“上海初升高”,選擇“星標公眾號”回復“加群”就能加入上萬家長信賴的升學群受到疫情的影響,今年各市重點的自招開放日報名遲遲沒有提上日程。但不管怎樣,自招應該是不會取消的,以下是去年四校及分校自招開放日情況匯總…

linux I/O 棧 預習(上)

二、預習 在我們進去device mapper的dm dedup學習之前,我們先要預習一下,什么是device mapper,和為什么device mapper能夠做塊重刪。 1、device mapper照舊,我們先看一下維基百科對它的介紹。The device mapper is a framework pr…

java.util.concurrent.RejectedExecutionException

報錯日志 java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask12e2cb93 rejected from java.util.concurrent.ThreadPoolExecutor6ecd396b[Running, pool size 10, active threads 10, queued tasks 200, completed tasks 0] 原因&am…

springboot controller 訪問 404

兩種解決方式: 1、因為SpringBoot的項目啟動類,會只掃描該包下的文件或者改包下所有子包內的文件,只要你把該文件移動到啟動類的相同目錄報下就可以。 2、就是在該類上面加者在啟動類上添加注解 ComponentScan(basePackages {"com.boota…

fegin需要實現類_【第24條】靜態成員類優于非靜態成員類

第24條靜態成員類優于非靜態成員類嵌套類(nested class)是指定義在另一個類的內部的類。嵌套類存在的目的應該只是為它的外圍類(enclosing class)提供服務。如果嵌套類將來可能會用于其他的某個環境中,它就應該是頂層類(top-level class)。嵌套類有四種:…

.h與.cpp

本質上沒什么區別。 cpp:c plus plus,就表示為c原文件。 .h文件實現的功能是聲明.cpp文件中需要使用的變量、函數及宏定義等。 .h文件就像是一個接口,具體的實現可以在.cpp中,也可以在.h中。轉載于:https://www.cnblogs.com/keguniang/p/9877581.html