1. 程式人生 > >Python程式設計導論(第二版)-學習筆記

Python程式設計導論(第二版)-學習筆記

語法和語義的差別

例子“

foo = 10 / 'abc'

用字面常量除以字串,==完全符合語法!==;但是不符合語義,因為使用數字除以字串是沒有任何意義的。

Python會進行靜態語義檢查,但是並不會報告全部語義錯誤;它們當中有些情況下會造成程式執行意料之外

小知識點

  1. Py2中print是直譯器的命令而Py3中print是一個函式
  2. type()
  3. ==除法使用//而不是’/’==
  4. **次方運算
  5. ==bool操作==:and or not
  6. Python自帶的IDE叫做IDLE,它只是一個人名也是一個喜劇團體名,並不是英文縮寫
  7. 常用的IDE:Anaconda Canopy
  8. 使用elif而不是else if
  9. 10 * ‘foo’ 重複10次,這時*稱為重複符,不是乘號
  10. print()的多個引數用逗號分隔時,每個引數輸出的時候回自動追加空格
  11. input(‘提示資訊…’)會將使用者的輸入解釋為str物件,至於程式希望得到使用者的輸入是數字,那麼得主動將其轉換為number或使用int()包裹input()函式
  12. 使用epsilon來給表示近似範圍的變數命名;如abs(a - b) < epsilon,則認為a、b近似
  13. 求平方根的邊界條件應該是answer ** 2 < number 而不是answer < number;其中answer是平方根而number是被求平方根的數
  14. ==別忘了可以使用in
    來檢查一個物件是否在另一個物件內出現或包含==
  15. 判斷是否是小寫字母:if c in ‘abcdefghijklmnopqrstuvwxyz’
  16. ==可以在函式內部定義函式,這一內部函式可以在函式中呼叫,稱為輔助函式==;例:def funcA(): def funcB():… funcB() # 在funcA內部定義函式funcB,然後funcA呼叫funcB
  17. 字串或容器集合處理的時候,注意用好切片功能
  18. 單元素元組必須帶括號
  19. 加號作用於元組的時候是連線而不是相加
  20. x,y,z=’abc’是序列化多重賦值,並不是僅僅對z賦值,xyz分別是abc
  21. 元組和字串都是不可變的,都能用索引來引用其元素但是都不能通過索引來修改它
  22. Python中元素其實就是一個名稱,它表示了這個名稱對應的繫結的變數,如,s=’aaa’表示s繫結到了物件sss
  23. ==對物件賦值,實際上就是建立了一個新的物件,然後將變數名稱繫結到了這個新的物件,舊的物件不再被引用,實際上並沒有修改舊物件。==修改一個變數後實際上是繫結到了新物件,因此id()函式返回值不同
  24. id()可以得到物件的唯一識別符號,可以判斷是不是同一個物件。
  25. 可以使用list(foo)等類似的函式拷貝容器
  26. ==執行深度拷貝,用標準庫copy的copy.deepcopy==
  27. [x ** 2 for x in range(10) if x > 100]
  28. 函式也是物件
  29. 高階函式:有至少一個引數是函式
  30. 內建了一個高階函式:map()可以使用
  31. 除了list,str tuple range都是不可變的
  32. 如果省略split的引數,那麼實際上用包括換行回車分頁製表空格在內的所有空白字元作為split字元
  33. dict是無序的,可以直接對dict[newKey]賦值得到新的鍵值對
  34. ==字典使用del來刪除元素而其他型別使用remove方法來進行刪除
  35. 允許過載操作符,通過過載特殊方法來實現
  36. 繼承:class Foo(Bar)
  37. ==務必主動顯式地呼叫基類的建構函式==,基類的_ init _不是自動呼叫的
  38. ==注意:return 一個容器並不是返回其副本而是返回其引用!!!,要想返回其副本必須使用全切片:return foo[:]==
  39. 在Py中使用類似MATLAB的功能,可以使用標準庫PyLab
  40. UNIX中的rc檔案:RuntimeConfig
  41. numpy除了多維陣列,還擁有大量線性代數的工具
  42. 最優化問題:比如一些需要求最大值最小值的問題
  43. 編寫的函式如果會呼叫到外部的其它函式,最好考慮一下要不要做成高階函式,即將函式物件作為引數傳遞進來。
  44. 揹包的最優解問題:可以使用暴力解貪婪演算法去解決
  45. 用貪婪法不一定能找到揹包問題的最優解,但是揹包中的物品是可以分解的即連續/分數揹包問題的時候,貪婪演算法一定可以找到最優解
  46. 資料視覺化圖表:plot chart ,資料結構中的圖:graph
  47. 動態規劃:當問題可以被分解為重複的子問題或存在子問題被處理多次的時候適用
  48. 斐波那契數列可以使用動態規劃備忘錄法,P156
  49. 概率分佈
  50. 正態分佈即高斯分佈,在均值處概率取最大值
  51. 條件概率:當某個事件B為真時,事件A的發生概率P(A|B)
  52. 貝葉斯定理:與條件概率密切相關
  53. 貝葉斯定理比常規條件概率更高階的地方:它考慮了B事件的置信度,即B事件為真的時候其準確為真的概率

lambda函式

lambda args:
函式體

‘//’執行整數除法,只返回結果的商而丟棄餘數;’/’執行浮點數除法

賦值特性

多重賦值

foo,bar = 10, 20

先對等號右側進行求值

SWAP賦值

foo,bar = bar, foo

生成序列

Py2中的range()在生成序列的時候會一次性將序列中的所有成員都生成並放入記憶體,這導致較大的資源佔用。Py3中的range()沒有這個問題,不會一次性生成所有成員。另外,Py2可以使用xran
ge()替代range(),xrange()與Py3的range()相同。

如果在range()求值之後,在for - in 程式碼塊內修改range()的範圍,此時對range()的範圍毫無影響,因為range()已經求值完成了,此時再做修改是沒有效果的。

窮舉法的限制和缺點

  • 複雜度高,需要窮舉才能得到結果
  • 本質是一種查詢技術,當正確答案包含在被查詢的集合(可以被窮舉出來的內容)中時才能得到結果

當窮舉集合中不包含正確結果時,無法得到正確結果;例:求25的平方根,使用窮舉法從1開始嘗試,每次遞增0.3,即按照1.0,1.3,1.6,…這樣的序列去嘗試,由於不可能得到數字5,因此這種窮舉法並不能得到正確結果5。

二進數對浮點型別的儲存問題

由於==二進位制數不能完美地儲存浮點數字,因此存在浮點數加減時的誤差==

foo = 0.0
for i in range(10):
    i += 0.1
print(foo)

結果是0.99999999而不是1.0。

計算機儲存二進位制數的原理

儲存數字的原理是:有效數字+指數:如1.949的有效數字可以是1949,指數為-3(實際儲存的時候要將這些數字轉換為二進位制值來儲存);即==儲存一個數就是以二進位制形式儲存其有效數字以及指數==。
總之,表示0.1是很困難的,只能無限接近。
==因此,10個0.1相加並不等於0.1乘上10==。與C相同,==浮點數之間比較不能直接用’==’而應該用abs(a - b) <= 0.001==。

使用round()可以指定浮點數保留小數點後多少位有效數字

比二分法更好的開方法:牛頓法

如果一個數guess是多項式P的一個根的近似值,那麼guess - P(guess)/P’(guess)就是一個更好的近似值。

不同於其他語言的讓人懵逼的一種變數作用域情況

如下例:

def func1():
    print(something)
something = 10
func1()
# 執行到此處輸出10

def func2():
    print(suprise)
    suprise = 10
suprise = 100
func2()
# 令人震驚的是,這裡不能打印出100也當然不可能打印出10;
# 反而會打印出一個錯誤命令
# UnboundLocalError: local variable 'suprise' referenced before assignment
# 本地變數未繫結錯誤: 本地變數 '驚訝' 在賦值之前被引用了
  • 這表明:第二個函式未能引用到全域性的變數
  • 第二個函式認為suprise未定義

原因分析:
- [x] 只要一個變量出現在了函式體內部,那麼在函式執行前,直譯器就已經確認了有這個變數的存在,此時,覆蓋外部、全域性所有/任何同名變數。(==函式在執行之前,其內部定義的所有變數已經在執行函式的第一行程式碼之前就被載入了==)
- [x] 雖然直譯器在函式執行前確認了叫這個名稱的變數的存在,但是隻要函式沒有執行到這個變數的賦值語句,那麼這個變數就是沒有賦值的。(==函式的第一行程式碼執行之前,其內部所有定義的變數都是一個沒有賦值的變數並且遮蔽外部其他重名變數==)
- [x] 因此,函式記憶體在的變數會遮蔽外部變數讓你無法引用到,這個全域性/外部變數被遮蔽了,被降維成函式內部的區域性變數,但是卻在執行到賦值語句的時候才對它賦值,在此之前對該變數的引用是對未定義的值進行引用。

一般來說,魯邦的Python程式碼,是應該努力避免變數名稱衝突的。命名技巧的應用:==把你的函式內部定義的變數的名稱修改一下:
- 增加下劃線
- 增加前後綴
- 大小寫變化
- …

如果不瞭解Python在函式執行前首先載入函式內部所有定義的變數這一特性,就會在命名重名的時候出現這種奇怪的錯誤。

遞迴完成迴文判斷

def isPal(s):
    if len(s) <= 1 :    # 遞迴結束條件:len <= 1,不可能是迴文
        return True
    else:
        return s[0] == s[-1] and isPal(s[1:-1])

不建議使用from foo import *

因為這樣雖然可以不使用模組名即可引用模組內的名稱,如foo.bar可以直接用bar來使用,但是這樣會導致可讀性降低,因為看到bar並不能完全斷定bar是屬於foo模組內的。另外,使用了這種import方式之後,通過模組名稱來引用成員的時候會報錯,提示模組名稱未定義。

模組被import之後,即使該模組的的程式碼被修改,也不會影響,仍然執行的是舊程式碼

修改模組程式碼後想使之生效,可以重啟Python直譯器

字典使用元組作為鍵的原因

字典的鍵必須滿足可雜湊,py中內建的不可變型別都是可雜湊的而可變型別都是不可雜湊的,因此可雜湊的元組是符合條件的

生成器

通過列表生成式,我們可以直接建立一個列表。但是,受到記憶體限制,列表容量肯定是有限的。而且,建立一個包含100萬個元素的列表,不僅佔用很大的儲存空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。

所以,如果列表元素可以按照某種演算法推算出來,那我們是否可以在迴圈的過程中不斷推算出後續的元素呢?這樣就不必建立完整的list,從而節省大量的空間。在Python中,這種一邊迴圈一邊計算的機制,稱為生成器(Generator)。

以下都是生成器:
- foo = [ x ** 2 for x in range(10)]
- yield

yield的作用

呼叫的函式內有yield時,在yield處返回,返回值是yield的表示式的值;下一次執行該函式時,從上一次yield返回的位置繼續執行。

>>> def odd():
...     print 'step 1'
...     yield 1
...     print 'step 2'
...     yield 3
...     print 'step 3'
...     yield 5
...
>>> o = odd()
>>> o.next()
step 1
1
>>> o.next()
step 2
3
>>> o.next()
step 3
5

yield應用例子

foo = [ x for x in range(1000000)]

def funcYield(foo):
    for item in foo:
        yield item

if 100 in funcYield(foo):
    print(True)

檢測某個值是否存在於某個集合。
==使用yileld的優點是:每次遍歷集合中的一個值就返回,如果此時符號條件,那麼接下來集合的其他內容就不用再遍歷了,不僅節省了計算時間還節省了記憶體空間,因為不再需要一次性生成完整的集合、生成集合中所有元素的副本了==。

圖的單遍歷問題

遍歷圖裡面的所有節點,要求每個節點只能被進出一次。
尤拉證明了:除了起點和終點以外,行走過程的每個點都必須被偶數條邊連線。
因此,如果所有節點都不是偶數條邊的話,那麼這個圖是不可能實現單遍歷的。

圖的表示

  • 程式碼表示

節點用一個類表示,邊用一個類,其中儲存了這條邊連線的起點和終點。
- 數學表示

可以使用鄰接矩陣或鄰接表來表示。

機器學習簡介

機器學習步驟
- 觀測訓練資料集
- 分析訓練資料集並進行擴充套件和建模
- 利用這個模型進行預測

監督式學習:從已有特徵向量去預測未知的特徵向量的對應值並進行標籤分類。其資料都是已經標記的資料。

非監督式學習:特徵集合/訓練資料沒有標記,目的是發現訓練資料集合中的隱含模式。
非監督式學習又分為隱變數方法和聚類方法。

  • 聚類方法:對集合中的各個資料進行劃分,將相似度高的劃分為一個子集。
  • 隱變數方法:隱變數不能被觀察到,它一般是通過可觀察到的變數推匯出來的,如從成績和測試推斷出學生的水平,水平就是訓練資料的隱變數。

聚類就是對一組物件找到當中相似的類,相當於對它們進行分類。

常見的監督式學習應用:建立分類模型;==分類模型又稱為分類器==,用於對樣本進行標註,即對樣本進行分類。

K最近鄰分類器,又稱為KNN分類器。

相關推薦

Python程式設計導論(第二)-學習筆記

語法和語義的差別 例子“ foo = 10 / 'abc' 用字面常量除以字串,==完全符合語法!==;但是不符合語義,因為使用數字除以字串是沒有任何意義的。 Python會進行靜態語義檢查,但是並不會報告全部語義錯誤;它們當中有些情況下會

Python之路第二天-----學習筆記

ati pop 可用 cor reverse 單詞 print 但是 進行 變量名要點: 1、變量名只能包含字母、 數字和下劃線。 變量名可以字母或下劃線打頭, 但不能以數字打頭, 例如, 可將變量命名為message_1, 但不能將其命名為1_message。 2、變量

python cookbook第三學習筆記十九:未包裝的函式新增引數

比如有下面如下的程式碼,每個函式都需要判斷debug的是否為True,而預設的debug為False def a(x,debug=False):     if debug:       

JavaScript高階程式設計第三學習筆記(一)之資料型別區分詳談

  null、NaN、undefined三者的區別是什麼?   在初次接觸到JavaScript的時候,傻傻的分不清null、NaN、undefined三者到底區別何在,在實際的專案開發中也因為這個問題而困惑久矣。針對這個問題,我特意查找了多方資料,在筆記本上做了詳細的分析記錄,但是由於紙質資料不便於攜帶、

Docker技術入門與實戰 第二-學習筆記-9-Docker Compose 專案-1-舉例說明

Docker Compose 是 Docker 官方編排(Orchestration)專案之一,負責快速在叢集中部署分散式應用 Compose 通過一個配置檔案來管理多個Docker容器,在配置檔案中,所有的容器通過services來定義,然後使用docker-compose

Docker技術入門與實戰 第二-學習筆記-8-網路功能network-1-單個host上的容器網路

Docker 中的網路功能介紹 Docker 允許通過外部訪問容器或容器互聯的方式來提供網路服務   1) 外部訪問容器

Docker技術入門與實戰 第二-學習筆記-8-網路功能network-2-相應配置

1) 快速配置指南(詳細使用下面會講) 其中有些命令選項只有在 Docker 服務啟動的時候才能配置,而且不能馬上生效 下面2個命令選項既可以在啟動服務時指定,也可以 Docker 容器啟動(doc

Docker技術入門與實戰 第二-學習筆記-8-網路功能network-3-容器訪問控制和自定義網橋

1)容器訪問控制 容器的訪問控制,主要通過 Linux 上的 iptables防火牆來進行管理和實現。 iptables是 Linux 上預設的防火牆軟體,在大部分發行版中都自帶。   容器訪問外部網路 容器要想訪問

Docker技術入門與實戰 第二-學習筆記-10-Docker Machine 專案-1-cli

Docker Machine 是 Docker 官方編排(Orchestration)專案之一,負責在多種平臺上快速安裝 Docker 環境 Docker Machine是一種工具,它允許你在虛擬主機上安裝Docker引擎,並使用docker-machine命令管理主機。

Android 第一行程式碼(第二)學習筆記(一)

onCreate()  活動第一次被建立的時候呼叫; onStart()   活動將要展示在前端時呼叫 onResume()  處於執行狀態,並且可以跟使用者互動 onPause()   活動即將從前臺退出 onStop()  活動完全不可見 onDestroy()   被

Android 第一行程式碼(第二)學習筆記

本人電腦是Mac mini 4G記憶體,真的小的可以,而且還是不能加記憶體條的那種,不過勉強還是能用。 開發工具用的Android studio 2.3  ,首先Android studio 2.3 官方建議在Mac下記憶體不低於3G,不過 我分配了2點多G用起來出來慢些

Android 學習之《Android程式設計權威指南》第二 程式碼+筆記整理(四)

(程式碼)GeoQuiz最終開發 GeoQuiz應用初步開發 GeoQuiz應用升級開發 解決GeoQuiz應用旋轉恢復第一題的BUG 不展示編譯器自動完成的程式碼,僅提供手動修改或者編寫的程式碼。 省略了先前一些程式碼,可參照上方連結。 升級內容: 增加作弊按鈕,給使用者提

Android 學習之《Android程式設計權威指南》第二 程式碼+筆記整理(三)

(程式碼)解決GeoQuiz應用旋轉恢復第一題的BUG 一、產生BUG的原因 1. 裝置旋轉時,系統會銷燬當前的QuizActivity例項,然後建立一個新的例項,這時陣列索引(mCurrentIndex)會初始化為0,因此使用者看到的還是第一道題目。 2.

Python語言程式設計(MOOC崇天)第二學習筆記python蟒蛇繪製+turtle庫)

                                               語法元素分析: 庫引用,使用import保留字完成。或者 from  庫名 import 函式名

讀書筆記--《Python基礎教程第二》-- 第五章 條件、循環和其他語句

ja5.1 print和import的更多信息5.1.1 使用獨號輸出>>> print ‘Age:‘,42Age: 42>>> 1,2,3(1, 2, 3)>>> print 1,2,31 2 3>>> print (1,2,3)(1,

讀書筆記--《Python基礎教程第二》--第六章 抽象

ja6.1 懶惰即美德>>> fibs=[0,1]>>> for i in range(8):... fibs.append(fibs[-2]+fibs[-1])... >>> fibs[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]6

讀書筆記--《Python基礎教程第二》--第七章 更加抽象

ja7.1 對象的魔力 多態 不同的類的對象使用同樣的操作 封裝 繼承7.1.1 多態 1、多態和方法 >>>object.getPrice() >>> ‘abc‘.count(‘a‘)1>>> [1,2,‘a‘].count(‘a‘)1>&

讀書筆記--《Python基礎教程第二》--第十一章 文件和素材

ja第十一章 文件和素材11.1 打開文件 open函數用來打開文件,語法如下: open(name[,mode[,buffering]]) f = open(r‘/home/python/somefile.txt‘)11.1.1 文件模式r 讀模式w 寫模式a 追加模式b 二進制模式(可添加到其他的模式

Python第二學習筆記(1)

學習筆記深淺拷貝 ==比較的是數據內容,如果是True意義為內容相同,引用並不同=操作執行後,前後兩個元素的引用地址相同 淺拷貝 copy() -> List 返回一個新的列表引用類型只拷貝引用地址 深拷貝 完全拷貝。包括引用類型 from copy import deepcopy lst2=deep

python基礎教程(第三)學習筆記(六)

第六章 抽象(函式) 6.1 懶惰是一種美德 6.2 抽象和結構 6.3 自定義函式 判斷某個物件是否可呼叫,可使用內建函式callable。格式是callable(物件)。 函式是結構化程式設計的核心。使用def(表示定義函式)語句。 '''   def fun(str_s): #