【數據科學系統學習】Python # 編程基礎[一]

關於數據科學在作什麼,咱們已經在前兩篇文章中進行了總結,即專題概述描述性統計分析。要進行數據科學的探索,須要一個「好工具」,就是Python。從本篇開始,將總結學習Python的學習要點。python


Python是什麼

官方對 Python 的介紹以下:正則表達式

「Python 是一款易於學習且功能強大的編程語言。 它具備高效率的數據結構,可以簡單又有效地實現面向對象編程。Python 簡潔的語法與動態輸入之特性,加之其解釋性語言的本質,使得它成爲一種在多種領域與絕大多數平臺都能進行腳本編寫與應用快速開發工做的理想語言。」

Python 名字的由來:編程

「Python 的創造者吉多·範羅蘇姆(Guido van Rossum)採用 BBC 電視節目《蒙提·派森的飛行馬戲團(Monty Python's Flying Circus,一譯巨蟒劇團)》的名字來爲這門編程語言命名。儘管他本人並不特別喜歡蟒蛇這種經過在獵物身邊捲曲本身的身體以此來碾碎獵物身體來進食的動物。」

基礎

字面常量

字面常量(Literal Constants)是諸如 五、1.23 這樣的數字,或者是如「這是一串文本」或「This is a string」這樣的文本。它們是字面上的,所用的就是它字面意義上的值或是內容。segmentfault

數字

數字主要分爲兩種類型——整數(Integers)與浮點數(Floats)。如 2 和 3.23 或 52.3E-4,其中 E 表示 10 的冪。數組

字符串

字符串(String)是字符(Characters)的序列(Sequence)。字符串是不可變的。數據結構

格式化方法
一個字符串可使用某些特定的格式(Specification),隨後,format 方法將被調用,使用這一方法中與之相應的參數替換這些格式。即將每一個參數值替換至格式所在的位置。舉例以下:編程語言

age = 14
name = 'Tom'

print('{0} is a {1} years old boy'.format(name, age))
print('{0} is a good boy'.format(name))」

此外,能夠指定更詳細的格式:函數

# 對於浮點數 '0.333' 保留小數點(.)後三位
print('{0:.3f}'.format(1.0/3))

# 使用下劃線填充文本,並保持文字處於中間位置
# 使用 (^) 定義 '___hello___'字符串長度爲 11
print('{0:_^11}'.format('hello'))

# 基於關鍵詞輸出 'Jack was confirmed as captain for the rest of the season'  
print('{name} was confirmed as {position} for the rest of the season'.format(name='Jack', position='captain'))

每次調用print將在獨立的一行中打印,即老是以換行符\n結尾,如有時需避免這一換行符,能夠end指定其結尾方式。例如以空白結尾:工具

print('a', end=' ')
print('b', end=' ')
print('c')

輸出a b c.學習

轉義序列
要輸入如What's your name?這樣的字符串有兩種方式。一種是使用雙引號"What's your name?",另外一種須要用到反斜槓\來指定單引號'What\'s your name?'。其它須要轉義的字符同理,經過反斜槓\來轉義,包括它自身。

原始字符串
在處理正則表達式時,應全程使用原始字符串,即在字符串前增長rR來指定一個原始字符串。如'\\1'能夠經過'r\1'來實現。

變量

變量的值是能夠變化的,便可以用變量儲存任何東西,只需經過一些方式訪問這些變量。

標識符命名

標識符(Identifiers)是爲某些東西提供的給定名稱。變量是標識符的一個例子。命名規則以下:

  • 第一個字符必須是字母表中的字母(大寫 ASCII 字符或小寫 ASCII 字符或 Unicode 字符)或下劃線(_)。
  • 標識符的其它部分能夠由字符(大寫 ASCII 字符或小寫 ASCII 字符或 Unicode 字符)、下劃線(_)、數字(0~9)組成。
  • 標識符名稱區分大小寫。

數據類型

變量能夠將各類形式的值保存爲不一樣的數據類型(Data Type)。基本的類型是數字字符串,在面向對象編程中將介紹如何經過來建立咱們本身的類型。

對象

Python 是強(Strongly)面向對象的,由於全部的一切都是對象, 包括數字、字符串與函數。

運算符與表達式

運算符

  • +
  • -
  • *
  • 乘方**
  • /
  • 整除//
  • 取模%
  • 左移<<
  • 右移>>
  • 按位與&
  • 按位或|
  • 按位異或^
  • 按位取反~
  • 小於<
  • 大於>
  • 小於等於<=
  • 大於等於>=
  • 等於==
  • 不等於!=
  • 布爾「非」not
  • 布爾「與」and
  • 布爾「或」or

表達式
在下面的例子中:

length = 5
breadth = 2

area = length * breadth
print('Area is', area)
print('Perimeter is', 2 * (length + breadth))

咱們將表達式 length * breadth 的結果存儲在變量 area 中並將其經過使用 print 函數打印出來。在第二種狀況中,咱們直接在 print 函數中使用了表達式 2 * (length + breadth) 的值。

控制流

在 Python 中有三種控制流語句,ifforwhile

條件

if age >= 18:

注意不要少寫了冒號:。

elifelse if的縮寫,徹底能夠有多個elif,因此if語句的完整形式就是:

if <條件判斷1>:
    <執行1>
elif <條件判斷2>:
    <執行2>
elif <條件判斷3>:
    <執行3>
else:
    <執行4>

if語句執行有個特色,它是從上往下判斷,若是在某個判斷上是True,把該判斷對應的語句執行後,就忽略掉剩下的elifelse

if判斷條件還能夠簡寫,好比寫:

if x:
    print('True')

只要x是非零數值、非空字符串、非空list等,就判斷爲True,不然爲False

循環
Python 的循環有兩種。

第一種是for...in循環,依次把listtuple中的每一個元素迭代出來

因此for x in ...循環就是把每一個元素代入變量x,而後執行縮進塊的語句。

Python 提供一個range()函數,能夠生成一個整數序列,再經過list()函數能夠轉換爲list。好比range(5)生成的序列是從 0 開始小於 5 的整數:
圖片描述

計算:
圖片描述

第二種循環是while循環:
圖片描述

在循環中,break語句能夠提早退出循環。
圖片描述

在循環過程當中,也能夠經過continue語句,跳過當前的此次循環,直接開始下一次循環。continue的做用是提早結束本輪循環,並直接開始下一輪循環。
圖片描述

要特別注意,不要濫用breakcontinue語句。breakcontinue會形成代碼執行邏輯分叉過多,容易出錯。大多數循環並不須要用到breakcontinue語句,上面的兩個例子,均可以經過改寫循環條件或者修改循環邏輯,去掉breakcontinue語句。

有些時候,若是代碼寫得有問題,會讓程序陷入「死循環」,也就是永遠循環下去。這時能夠用Ctrl+C退出程序,或者強制結束 Python進程。

函數

函數是什麼

函數(Functions)是指可重複使用的程序片斷。它們容許你爲某個代碼塊賦予名字,容許你經過這一特殊的名字在你的程序任何地方來運行代碼塊,並可重複任何次數。這就是所謂的調用(Calling)函數。

在 Python 中,函數能夠經過關鍵字 def 來定義。這一關鍵字後跟一個函數的標識符名稱,再跟一對圓括號,其中能夠包括一些變量的名稱,再以冒號結尾,結束這一行。隨後而來的語句塊是函數的一部分。

在定義函數時給定的名稱稱做「形參」(Parameters),在調用函數時你所提供給函數的值稱做「實參」(Arguments)。

調用函數

要調用一個函數,須要知道函數的名稱和參數。函數的參數只是輸入到函數之中,以便咱們能夠傳遞不一樣的值給它,並得到相應的結果。

Python 內置的經常使用函數包括數據類型轉換函數,好比int()函數能夠把其餘數據類型轉換爲整數。用input()讀取用戶的輸入:
clipboard.png

由於input()返回的數據類型是strstr不能直接和整數比較,必須先把str轉換成整數。Python 提供了int()函數來完成這件事情:
clipboard.png

函數名其實就是指向一個函數對象的引用,徹底能夠把函數名賦給一個變量,至關於給這個函數起了一個「別名」:
clipboard.png

若是函數調用出錯,必定要學會看錯誤信息。

定義函數

在 Python 中,定義一個函數要使用def語句,依次寫出函數名、括號、括號中的參數和冒號:,而後,在縮進塊中編寫函數體,函數的返回值用return語句返回。

在 Python 交互環境中定義函數時,注意 Python 會出現...的提示。函數定義結束後須要按兩次回車從新回到>>>提示符下:
clipboard.png

若是你已經把my_abs()的函數定義保存爲abstest.py文件了,那麼,能夠在該文件的當前目錄下啓動Python 解釋器,用from abstest import my_abs來導入my_abs()函數,注意abstest是文件名(不含.py擴展名)。

定義一個什麼事也不作的空函數,能夠用pass語句:

def nop():
    pass

pass語句什麼都不作,實際上它能夠用做爲佔位符,好比如今還沒想好怎麼寫函數的代碼,就能夠先放一個pass,讓代碼能運行起來。

pass還能夠用在其餘語句裏,好比:

if age >= 18:
    pass

缺乏了pass,代碼運行就會有語法錯誤。

數據類型檢查能夠用內置函數isinstance()實現。

Python 的函數返回多值其實就是返回一個tuple;Python 函數返回的是單一值時,返回值仍然是一個tuple。可是,在語法上,返回一個tuple能夠省略括號,而多個變量能夠同時接收一個tuple,按位置賦給對應的值。函數能夠同時返回多個值,但其實就是一個tuple

函數執行完畢也沒有return語句時,自動return None

函數的參數

Python 的函數定義很是簡單,但靈活度卻很是大。除了正常定義的必選參數外,還可使用默認參數可變參數關鍵字參數,使得函數定義出來的接口,不但能處理複雜的參數,還能夠簡化調用者的代碼。

位置參數:
clipboard.png

power(x, n)函數有兩個參數:xn,這兩個參數都是位置參數,調用函數時,傳入的兩個值按照位置順序依次賦給參數xn

默認參數:
對於一些函數來講,你可能爲但願使一些參數可選並使用默認的值,以免用戶不想爲他們提供值的狀況。默認參數值能夠有效幫助解決這一狀況。你能夠經過在函數定義時附加一個賦值運算符=來爲參數指定默認參數值。要注意到,默認參數值應該是常數。更確切地說,默認參數值應該是不可變的。

clipboard.png

n = 2 是默認參數

定義默認參數要牢記一點:默認參數必須指向不變對象。且只有那些位於參數列表末尾的參數才能被賦予默認參數值,意即在函數的參數列表中擁有默認參數值的參數不能位於沒有默認參數值的參數以前。
 

可變參數:
有時你可能想定義的函數裏面可以有任意數量的變量,也就是參數數量是可變的,這能夠經過使用星號來實現。即傳入的參數個數是可變的。

clipboard.png
clipboard.png

咱們聲明一個諸如 *param 的星號參數時,今後處開始直到結束的全部位置參數(Positional Arguments)都將被收集並聚集成一個稱爲param的元組(Tuple)。

相似地,當咱們聲明一個諸如 **param 的雙星號參數時,今後處開始直至結束的全部關鍵字參數都將被收集並聚集成一個名爲 param字典(Dictionary)

關鍵字參數:
若是你有一些具備許多參數的函數,而你又但願只對其中的一些進行指定,那麼你能夠經過命名它們來給這些參數賦值——這就是關鍵字參數(Keyword Arguments)——咱們使用命名(關鍵字)而非位置來指定函數中的參數。

關鍵字參數容許你傳入 0 個或任意個含參數名的參數,這些關鍵字參數在函數內部自動組裝爲一個dict

舉個例子,擴展函數的功能。試想你正在作一個用戶註冊的功能,除了用戶名和年齡是必填項外,其餘都是可選項,利用關鍵字參數來定義這個函數就能知足註冊的需求。
clipboard.png

和可變參數相似,也能夠先組裝出一個dict,而後,把該dict轉換爲關鍵字參數傳進去:
clipboard.png

命名關鍵字參數:
若是要限制關鍵字參數的名字,就能夠用命名關鍵字參數,例如,只接收cityjob做爲關鍵字參數。這種方式定義函數並調用:
clipboard.png

和關鍵字參數**kw不一樣,命名關鍵字參數須要一個特殊分隔符**後面的參數被視爲命名關鍵字參數。

命名關鍵字參數必須傳入參數名,這和位置參數不一樣。若是沒有傳入參數名,調用將報錯。

使用命名關鍵字參數時,要特別注意,若是沒有可變參數,就必須加一個*做爲特殊分隔符。若是缺乏*,Python 解釋器將沒法識別位置參數和命名關鍵字參數,即缺乏 *cityjob被視爲位置參數。

clipboard.png

參數組合:
在 Python 中定義函數,能夠用必選參數、默認參數、可變參數、關鍵字參數和命名關鍵字參數,這 5 種參數均可以組合使用。

可是參數定義的順序必須是:必選參數、默認參數、可變參數、命名關鍵字參數和關鍵字參數。雖然能夠組合多達 5 種參數,但不要同時使用太多的組合,不然函數接口的可理解性不好。

經過一個tupledict,你也能夠調用函數:
clipboard.png

對於任意函數,均可以經過相似func(*args, **kw)的形式調用它,不管它的參數是如何定義的。

遞歸函數

若是一個函數在內部調用自身自己,這個函數就是遞歸函數。理論上,全部的遞歸函數均可以寫成循環的方式,但循環的邏輯不如遞歸清晰。

使用遞歸函數須要注意防止棧溢出。在計算機中,函數調用是經過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。因爲棧的大小不是無限的,因此,遞歸調用的次數過多,會致使棧溢出。

經過下面的代碼能夠查看你的電腦最大算到多少:
clipboard.png

解決遞歸調用棧溢出的方法是經過尾遞歸優化,事實上尾遞歸和循環的效果是同樣的,因此,把循環當作是一種特殊的尾遞歸函數也是能夠的。

尾遞歸是指,在函數返回的時候,調用自身自己,而且,return語句不能包含表達式。這樣,編譯器或者解釋器就能夠把尾遞歸作優化,使遞歸自己不管調用多少次,都只佔用一個棧幀,不會出現棧溢出的狀況。

要改爲尾遞歸方式,須要多一點代碼,主要是要把每一步的乘積傳入到遞歸函數中。Python 標準的解釋器沒有針對尾遞歸作優化,任何遞歸函數都存在棧溢出的問題。

clipboard.png


參考連接:
簡明Python教程(電子書可閱讀)
廖雪峯Python教程

若有不足,歡迎指正。

相關文章
相關標籤/搜索