python內
① 為什麼python內置的sort比自己寫的快速排序快100倍
主要原因,內置函數用C寫的。在Python語言內無論如何造不出內置函數的輪子。這也是通常C跟C++語言用戶更喜歡造基礎演算法的輪了的原因。因為C/C++用戶真有條件寫出匹敵標准庫的演算法,但很多高級語言不行,不是程序員技術差,是客觀條件就根本做不到。
你比如說Java語言沒人造字元串的輪子,C++光一個字元串類就有無數多的實現。是因為C+用戶更喜歡寫字元串類嗎?顯然不是,一方面是因為Java語言內沒法造出匹敵Java內置標准庫演算法的輪子,而C++真的可以,另外一個比較慘的原因是C++標准庫的字元串功能太弱了,大多數高級語言的字元串類功能都比C+標准庫字元串類功能更強。
Cpp內置的排序是快排和堆排的結合,最壞時間復雜度為nlogn,而快排最壞是n2。至於python內部的排序,我認為是一個道理,不會簡簡單單是一個快排,舉個簡單例子,當你數據已經是有序的時候,再傳入快排肯定就不合適。那你設置排序函數的時候,是不是預先將他打亂,再進行快排會更好呢。當然具體不會這么簡單,只是我認為官方給的介面都是很精妙的,很值得學習。
一方面Python中sort函數是用C語言寫的,C++內部的sort是由快排,直接插入和堆排序混合的,當數據量比較大的時候先用的快排,當數據量小的時候用直接插入,因為當數據量變小時,快排中的每個部分基本有序,接近直接插入的最好情況的時間復雜度O(n),就比快排要好一點了。
另外一方面這個的底層實現就是歸並排序。,只是使用了Python無法編寫的底層實現,從而避免了Python本身附加的大量開銷,速度比我們自己寫的歸並排序要快很多,所以說我們一般排序都盡量使用sorted和sort。
② Python 的內存管理機制
Python採用自動內存管理,即Python會自動進行垃圾回收,不需要像C、C++語言一樣需要程序員手動釋放內存,手動釋放可以做到實時性,但是存在內存泄露、空指針等風險。
Python自動垃圾回收也有自己的優點和缺點:優點:
缺點:
Python的垃圾回收機制採用 以引用計數法為主,分代回收為輔 的策略。
先聊引用計數法,Python中每個對象都有一個核心的結構體,如下
一個對象被創建時,引用計數值為1,當一個變數引用一個對象時,該對象的引用計數ob_refcnt就加一,當一個變數不再引用一個對象時,該對象的引用計數ob_refcnt就減一,Python判斷是否回收一個對象,會將該對象的引用計數值ob_refcnt減一判斷結果是否等於0,如果等於0就回收,如果不等於0就不回收,如下:
一個對象在以下三種情況下引用計數會增加:
一個對象在以下三種情況引用計數會減少:
驗證案例:
運行結果:
事實上,關於垃圾回收的測試,最好在終端環境下測試,比如整數257,它在PyCharm中用下面的測試代碼列印出來的結果是4,而如果在終端環境下列印出來的結果是2。這是因為終端代表的是原始的Python環境,而PyCharm等IDE做了一些特殊處理,在Python原始環境中,整數緩存的范圍是在 [-5, 256] 的雙閉合區間內,而PyCharm做了特殊處理之後,PyCharm整數緩存的范圍變成了 [-5, 無窮大],但我們必須以終端的測試結果為主,因為它代表的是原始的Python環境,並且代碼最終也都是要發布到終端運行的。
好,那麼回到終端,我們來看兩種特殊情況
前面學習過了,整數緩存的范圍是在 [-5, 256] 之間,這些整數對象在程序載入完全就已經駐留在內存之中,並且直到程序結束退出才會釋放佔有的內存,測試案例如下:
如果字元串的內容只由字母、數字、下劃線構成,那麼它只會創建一個對象駐留在內存中,否則,每創建一次都是一個新的對象。
引用計數法有缺陷,它無法解決循環引用問題,即A對象引用了B對象,B對象又引用了A對象,這種情況下,A、B兩個對象都無法通過引用計數法來進行回收,有一種解決方法是程序運行結束退出時進行回收,代碼如下:
前面講過,Python垃圾回收機制的策略是 以引用計數法為主,以分代回收為輔 。分代回收就是為了解決循環引用問題的。
Python採用分代來管理對象的生命周期:第0代、第1代、第2代,當一個對象被創建時,會被分配到第一代,默認情況下,當第0代的對象達到700個時,就會對處於第0代的對象進行檢測和回收,將存在循環引用的對象釋放內存,經過垃圾回收後,第0代中存活的對象會被分配為第1代,同樣,當第1代的對象個數達到10個時,也會對第1代的對象進行檢測和回收,將存在循環引用的對象釋放內存,經過垃圾回收後,第1代中存活的對象會被分配為第2代,同樣,當第二代的對象個數達到10個時,也會對第2代的對象進行檢測和回收,將存在循環引用的對象釋放內存。Python就是通過這樣一種策略來解決對象之間的循環引用問題的。
測試案例:
運行結果:
如上面的運行結果,當第一代中對象的個數達到699個即將突破臨界值700時(在列印699之前就已經回收了,所以看不到698和699)進行了垃圾回收,回收掉了循環引用的對象。
第一代、第二代、第三代分代回收都是有臨界值的,這個臨界值可以通過調用 gc.get_threshold 方法查看,如下:
當然,如果對默認臨界值不滿意,也可以調用 gc.set_threshold 方法來自定義臨界值,如下:
最後,簡單列出兩個gc的其它方法,了解一下,但禁止在程序代碼中使用
以上就是對Python垃圾回收的簡單介紹,當然,深入研究肯定不止這些內容,目前,了解到這個程度也足夠了。
③ python求和
python求和方法如下:
一、整數求和
Python內的整數求和非常簡單,就和平時日常中做的數學計算是一樣的過程。使用算術運世昌枝演算法把要求迅笑和的整數相加即可。
二、列表內的元素進行求和
有時候需要進行求和的數字是存放在一個或者多個列表之中的,那麼列表中的元素進行求和方法如下:
(1)單個列表求和
(2)多個列表求和
三、浮點數求和
因為python之中浮點數計算的特性,在涉及到小數點後多位計算時會出現一些很小的偏差。為了彌補這個偏差,就需要使用外部的庫來解決。
關於Python概述:
由荷蘭數學和計算機科學研究學會的Guido van Rossum於1990年代初設計,作為一門叫做ABC語言的替代品;Python提供了高效的高級數據結構,還能簡單有效地面向對象編程;目前Python是一門計算機編程語言。
Python最初是用來編寫自動化腳本,隨著不斷的發展,目前Python被用於大型項目的開搜敏發。目前Python是一門計算機編程語言,是直接面向對象動態語言,同時也是一種高級語言。
④ 在 Python 中使用二維數組
如果你需要使用二維數組,在 Python 中,除了 numpy 這個包之外,最簡單的方式就是使用 list 了。你可能認為可以這樣構建:
但是請你再仔細想一想,這樣做真的沒有問題嗎?
不要忘記了, Python 一切都是對象 這個問題,對象肯定存在引用的問題,尤其是可變對象。我們試著來改變其中一個元素:
很不幸,不是我們想像的那樣,它改變了多個元素。
來看一看 [ [0] * m ] * n 這個表達式,它首先創建 a = [ [0] * 4] ,然後構造 array = [a] * 3 ,這里 array 裡面是 a 的 3 個引用。
正確的構造,應該使用 列表推導式 ,而且非常 Pythonic :