06_Python基礎課程
Python基礎課程概述
本文件分為三大部分, 分別如下:
- Python開發環境
- Python語法規則
- Python容器
1 Python開發環境
- 能夠說出計算機有哪兩部分組成
- 能夠說出作業系統的作用
- 能夠說出程式語言的作用
- 能夠說出直譯器的作用
- 能夠說出Python直譯器種類
- 能夠說出目前Python主流的兩大版本是哪些
- 能夠說出在不同系統上搭建Python開發環境的流程
- 知道Python語言歷史、優缺點、應用領域
1.1 計算機組成
計算機是可以進行數值計算和邏輯運算, 並且具有儲存功能的電子機器.
計算機由硬系統件和軟體系統組成.
1.1.1 硬體系統
主要分為主機和外設兩部分,是指那些構成計算機系統的物理實體,它們主要由各種各樣的電子器件和機電裝置組成。
- 運算器: 負責資料的算術運算和邏輯運算,即資料的加工處理.
- 控制器: 是整個計算機的中樞神經,分析程式規定的控制資訊,並根據程式要求進行控制,協調計算機各部分元件工作及記憶體與外設的訪問等.
- 運算器和控制器統稱中央處理器(即CPU).
- 儲存器: 實現記憶功能的部件,用來儲存程式、資料和各種訊號、命令等資訊,並在需要時提供這些資訊.
- 輸入裝置: 實現將程式、原始資料、文字、字元、控制命令或現場採集的資料等資訊輸入到計算機.
- 輸出裝置: 實現將計算機處理後生成的中間結果或最後結果(各種資料符號及文字或各種控制訊號等資訊)輸出出來.
1.1.2 軟體系統
主要分為系統軟體和應用軟體,是指計算機證執行所需的各種各樣的計算機程式。
系統軟體的任務是既要保證計算機硬體的正常工作,又要使計算機硬體的效能得到充分發揮,並且為計算機使用者提供一個比較直觀、方便和友好的使用介面.
1.1.2.1 作業系統
- 沒有安裝作業系統的計算機, 通常被稱為裸機
- 如果想在裸機上執行自己所編寫的程式, 就必須用機器語言書寫程式
作業系統提供以下功能:
-
給使用者間接操作硬體的方式
- 圖形視窗方式
- 終端命令方式
-
給開發者提供的間接操作硬體的方式
- 系統呼叫
簡言之: 主要作用是管理好硬體裝置, 併為使用者和開發者提供一個簡單的介面, 以便於使用.
1.1.2.2 驅動程式
驅動程式: 驅動程式指的是裝置驅動程式, 是一種可以使計算機和裝置通訊的特殊程式. 作業系統通過這個程式操作和控制硬體裝置工作, 如果某裝置的驅動程式沒有正確安裝, 該裝置則無法工作. 所以一般作業系統安裝完畢之後,首要就是要安裝硬體裝置的驅動程式, 不過大多數情況下, 我們並不需要安裝驅動程式, 例如硬體、顯示器、光碟機就不需要安裝驅動程式, 而顯示卡、音效卡、攝像頭、印表機等就需要安裝驅動程式.
比如, 讓音效卡播放音樂, 它首先會發送響應的指令到音效卡驅動程式, 音效卡驅動程式接受到後, 馬上將其翻譯成音效卡才能聽懂的電子訊號命令, 從而讓音效卡播放音樂.
簡言之, 驅動程式提供了硬體到作業系統的一個介面以及協調二者之間的關係. 扮演者硬體和作業系統之間的一個橋樑的作用.
1.1.3 計算機執行程式的過程
我們從計算機如何播放音樂, 來了解計算機執行程式的過程.
- 雙擊應用程式, 應用程式中的指令和資料就會載入到記憶體中.
- CPU從記憶體中獲取指令並執行, 在記憶體中儲存執行之後的資料.
- CPU控制硬體進行相應的操作.
1.1.4 小結
-
計算機是能夠進行數值運算、邏輯運算, 並且具有儲存功能的電子裝置.
-
計算機由硬體系統和軟體系統構成.
-
計算機中所有程式的執行都是在記憶體中進行的, 暫時存放CPU中的運算資料.
-
作業系統的作用就是來管理硬體, 為普通使用者和開發者提供一種間接控制硬體的方式.
-
作業系統為普通使用者提供了終端、圖形化操作硬體的方式.
-
作業系統為開發者提供了系統呼叫操作硬體的方式.
-
驅動程式扮演作業系統和硬體之間的橋樑.
1.2 程式語言
1.2.1 程式語言
我們如何根據自己的需求控制硬體? 程式語言
程式語言(計算機語言)是人們為了控制計算機, 而設計的一種符號和文字的組合,從而實現向計算機發出指令.
- 形式是符號和文字的組合.
- 目的是為了控制計算機硬體.
Python語言就是一種程式語言, 由符號和文字組成的, 使用Python語言的目的就是為了控制計算機硬體進行工作.
1.2.2 直譯器
程式語言是文字和符號的組合, CPU只能認識機器指令, 機器指令的表現方式就是0和1的組合. 這顯然很矛盾?
此時, 需要一箇中間角色負責將文字和符號轉換為機器指令, 這個負責轉換的角色叫做直譯器. 直譯器本質上就是一個執行在作業系統上的應用程式.
Python語言如果想要被CPU讀懂,也需要一箇中間的翻譯程式.
1.2.3 Python 語言直譯器
Python語言是解釋型程式, 也就是說Python語言是讀一行解釋執行一行的方式進行工作的. 直譯器是一個程式, 那麼可以使用其他的程式語言來編寫這個直譯器.
- 使用C語言編寫的CPython直譯器(官方版本).
- Java語言編寫的Jython直譯器.
- C#語言編寫的IronPython直譯器.
- Python語言編寫的PyPy直譯器.
1.2.4 小結
- Python語言是符合和文字的組合, 目的是用來向計算機發送指令, 控制計算機工作.
- Python直譯器是執行在作業系統之上的一個特殊功能的應用程式.
- 直譯器負責將程式語言的符合和文字轉換為計算機能夠識別的計算機語言.
- Python直譯器程式可以由不同的語言的編寫, 官方直譯器使用C語言編寫,
我們在Windows上編寫的Python程式是否可以在Linux、Mac或者其他種類的作業系統上執行呢? 如果希望在其他作業系統上執行, 我們需要做哪些工作呢?
1.3 Python 語言介紹
1.3.1 Python 作者簡介
Python 的作者, Guido von Rossum (吉多·範·羅蘇姆, 中國Python程式設計師都叫他龜叔), 荷蘭人. 1982年, 龜叔從阿姆斯特丹大學獲得了數學和計算機碩士學位. 然而, 儘管他算得上是一位數學家, 但他更加享受計算機帶來的樂趣. 用他的話說, 雖然擁有數學和計算機雙料資質, 他總趨向於做計算機相關的工作, 並熱衷於做任何和程式設計相關的事情.
1.3.2 Python 語言的發展歷史
- 80 年代個人電腦浪潮, 電腦配置很低, 所以大家都使用類似於C語言這樣的程式語言, 但使用C語言使得程式設計師必須像計算機一樣思考, 寫出符合機器口味的程式. 不利於我們使用人思考問題的方式解決問題, 對於一些複雜問題, 會使得編碼比較複雜.
- 吉多希望編碼簡單, 功能又強大. 於是在 1991 年, 誕生了第一個 C 語言實現的 Python 直譯器.
- 計算機硬體越來越強大, Python 又容易使用, 所以許多人開始轉向 Python. 這些來自不同領域的開發者, 將不同領域的優點帶給了 Python.
- 從 Python 2.0開始, Python 轉為完全開源的開發方式, Python 也獲得了更加高速的發展.
1.3.3 Python 語言的版本
Python 目前有兩個版本, Python2 和 Python3, 最新版分別為 2.7.15 和 3.6.5, 其中 Python2 截止到 2020 年停止更新.
1.3.4 Python 語言的優缺點
- 易學. Python 有極其簡單的語法, 學習極其容易上手.
- 開源.
- 可移植性. Python 已經被移植在許多平臺上. 這些平臺包括 Linux、Windows、Mac OS、FreeBSD、WindowsCE 甚至還有 Symbian、Android 平臺.
- 豐富的庫. Python 標準庫確實很龐大. 除了標準庫以外,還有許多其他高質量的庫.
1.3.5 Python 語言的應用領域
- Web應用開發.
- 網路爬蟲.
- 桌面軟體.
- 作業系統管理.
- ...
1.3.6 小結
- Python 的作者叫吉多.
- 第一個 Python 直譯器誕生於 1991 年.
- Python 目前存在兩大版本, Python2 和 Python3, 主流版本為 Python3.
- Python 簡單、易學、開源、擴充套件性強、有豐富的庫.
- Python 可以用來做 Web 網站、網路爬蟲、作業系統管理.
1.4 Python開發環境搭建
Python 程式開發一般包含兩部分, 編寫 Python 程式和執行 Python 程式, 所以一個 Python 開發環境主要包含兩部分:
- 編輯Python程式碼的編輯器.
- 執行Python程式碼的直譯器
1.4.1 Python直譯器 + 普通文字編輯器
普通文字編輯器我們可以使用 Windows 系統自帶的 txt 文字編輯器、notepad++、sublime、editplus、ue 等等. 任何能夠進行文字編輯的軟體都可以作為 Python 程式開發的程式碼編輯器.
1.4.2 Python直譯器 + 互動式終端
在安裝 Python 直譯器時安裝了互動式終端. 我們可以通過在命令列視窗中, 輸入 Python 或者 Python2 或者Python3 進入不同 Python 版本的互動式終端.
1.4.3 Python直譯器 + 整合開發環境(IDE)
整合開發環境(IDE,Integrated Development Environment)是用於提供程式開發環境的應用程式, 一般包括程式碼編輯器、編譯器、偵錯程式和圖形使用者介面等工具. 集成了程式碼編寫功能、分析功能、編譯功能、除錯功能等一體化的開發軟體服務套. 所有具備這一特性的軟體或者軟體套(組)都可以叫整合開發環境.
我們使用PyCharm這款整合開發環境(IDE). 該軟體提供了 Windows、Linux、Mac三個版本, 可依據實際開發平臺選擇.
PyCharm的具體使用, 演示內容如下:
-
PyCharm 在 Windows、Linux、Mac 都有對應版本.
-
如何建立專案, 注意不同版本的 PyCharm 在建立專案時指定直譯器.
-
介紹 PyCharm 編輯器的各個專案結構區域、程式碼編輯區域、以及如何執行一個python 程式.
-
介紹如何配置 PyCharm 的字型、顏色、風格, 以及如何配置專案直譯器.
1.4.4 小結
- Python 的開發環境包含兩部分: Python 直譯器和程式碼編輯器.
- 編寫 Python 程式可以使用普通文字編輯器、互動式終端環境、整合開發環境.
- 我們在開發中主要使用整合開發環境 PyCharm.
2 Python基礎語法
學習目標:
- 能夠說出註釋的作用以及使用註釋的語法
- 能夠說出什麼是識別符號、什麼是關鍵字
- 能夠說出變數的作用
- 能夠說出變數型別的作用
- 能夠說出不同型別的資料之間的運算規則
- 能夠說出 Python 中的運算子的種類
- 能夠說出 print 函式的作用
- 能夠說出 input 函式的作用
- 能夠說出為什麼要進行型別轉換
- 能夠說出在 Python 中如何定義變數
- 能夠說出 if 分支語句的作用
- 能夠說出 if 語句的語法格式
- 能夠說出 while 迴圈語句的作用
- 能夠說出 while 迴圈的語法格式
- 能夠說出 break 在迴圈語句中的作用
- 能夠說出 continue 在迴圈語句中的作用
- 能夠說出函式的作用
- 能夠說出函式定義的的語法格式
- 能夠說出函式編寫的單一職責原則是什麼
- 能夠說出函式文件的作用
2.1 註釋
2.1.1 註釋的作用
註釋是編寫程式時, 寫程式的人給一個語句、程式段、函式等的解釋或提示, 能提高程式程式碼的可讀性.
註釋就是對程式碼的解釋和說明, 其目的是讓人們能夠更加輕鬆地瞭解程式碼.
2.1.2 註釋語法格式
單行註釋
# 這是註釋內容
print('hello world!')
print('hello world!') # 在程式碼後也可以編寫註釋
多行註釋
"""
程式碼完成的功能是, 列印輸出hello world
1. 首先呼叫 print 函式
2. 給 print 函式傳入要列印輸出的引數
"""
print('hello world!')
快捷鍵註釋
Win: ctrl + /
Mac: command + /
2.1.3 小結
- 註釋的作用是解釋說明程式碼.
- 註釋分為單行註釋和多行註釋.
- PyCharm 可以使用 ctrl + / 註釋快捷鍵.
- 註釋的恰當用法是彌補我們無法用程式碼表達意圖. 當代碼修改時, 程式設計師要堅持維護自己的註釋.
2.2 變數
2.2.1 變數的作用
編寫程式的目的就是將待處理的資料, 經過程式計算, 得出結果資料.
計算器舉例:
- 我們通過鍵盤輸入的運算元.
- 程式是否需要獲得鍵盤輸入的資料? 獲得資料之後是否要將資料臨時儲存, 便於後續計算?
- 輸出運算結果
變數是在程式執行過程中, 臨時儲存程式所需要計算的資料.
2.2.2 變數定義語法
變數在程式中表現為一個唯一不重複的名字, 只需定義一個名字, 給這個名字變數賦值即可.
注意:變數意味著儲存的資料是可以變化的.
# 定義一個變數,名字為 val, 這個變數臨時儲存的值為 100
val = 100
# 下面將這個變數的值,更改為其他的值 200
val = 200
注意: 這裡的等號(=), 叫做賦值運算子, 表示將=號後面的資料儲存到名字為=號前面的名字變數裡.
取變數名時應該遵循的規範:
- 識別符號由字母、下劃線和數字組成,且數字不能開頭.
- python中的識別符號是區分大小寫的.
- 變數名一般用小寫加下劃線組成.
- 不能和關鍵字和已有的名字衝突.
2.2.3 變數的型別
我們臨時儲存資料的目的是為了計算, 獲取最終結果. 資料在運算過程中, 不同型別的資料之間的運算規則是不同的.
例如: 兩個整數的運算規則和一個是整數、一個是'abc'字串運算規則是不一樣的.也就是說在資料運算過程中, 不同的資料型別約束了資料之間的運算規則.
下面我們先了解下, 在 Python 中的資料都有哪些型別?
- 數字型別: 整數和小數
- 符串型別: 除了數字型別的資料, 我們處理更多的就是字串型別資料, 例如 Word 中編輯文字, 其實就是在處理文字資訊, 這些文字資訊就是字串型別.在 Python 程式裡, 無論任何字元寫到兩個單引號或者雙引號內部, 我們稱之為字串. 例如: 'abcd'
- 布林型別: 用於表示邏輯運算結果, 該變數只有兩個值, rue 或 False.
注意: Python中定義變數時不需要指定型別, Python 會根據變數的值來推導變數的型別. 我們可使用 type() 函式來檢視變數的型別.
函式指的是一個單獨的功能. type 函式的功能就是獲得變數的型別.
2.2.4 不同型別之間的運算規則
Python 提供了兩種: 算術運算子和複合運算子.
算數運算子
運算子 | 描述 |
---|---|
+ | 加 |
- | 減 |
* | 乘 |
/ | 除 |
// | 取整數 |
% | 取餘數 |
** | 冪 |
複合賦值運算子
運算子 | 描述 |
---|---|
+= | 加法賦值運算子 |
- | 減法賦值運算子 |
* | 乘法賦值運算子 |
/ | 除法賦值運算子 |
// | 取整數賦值運算子 |
% | 取餘數賦值運算子 |
** | 冪賦值運算子 |
注意:
- 數字和數字之間可以進行所有的運算
- 數字和字串之間只能進行乘法運算.
- 字串和字串之間可以進行加法運算.
2.2.5 變數的輸入和輸出
輸入和輸出,都是相對於程式而言的。輸入和輸出,簡稱I/O(input/output)
- 從鍵盤讀取資料到程式中, 並且從程式中將資料顯示到螢幕, 叫做標準輸入和輸出.
- 從檔案讀取資料到程式中, 並且從程式中將資料儲存到檔案, 叫做檔案輸入和輸出.
- 從網路讀取資料到程式中, 並且從程式中將資料傳送到網路, 叫做網路輸入和輸出.
我們本小節學習標準輸入和輸出. 我們知道資料的接收和傳送需要依賴於計算機作業系統來控制硬體裝置來完成, 內部實現機制很複雜, 但 Python 將這些複雜的步驟封裝起來, 給了我們一種極其簡單的實現方式. 通過呼叫 print 函式和 input 函式來完成.
函式, 可以理解為封裝了某一個功能, 我們不必關心功能如何實現, 只需要怎麼使用即可.
2.2.5.1 print 函式使用
print 用於向螢幕輸出資料. 分為普通輸出和格式化輸出.
-
普通輸出變數
# 定義一個整數型別變數 my_number = 100 # 定義一個字串型別變數 my_string = 'hello itcast' # 輸出兩個變數 print(my_number) print(my_string)
-
格式化輸出變數
格式化輸出就是讓資料按照一定的格式輸出, 例如:我的名字是XXX
進行格式化輸出的流程;
- 先定義輸出格式.
- 在格式中填充資料.
案例: 已知有資料: name = '司馬二狗', age = 30, salary = 19988.78, 請按照 "我的名字是xxx, 我的年齡是xxx, 我的工資是xxx" 的格式將變數輸出.
定義輸出格式, 需要用到格式化佔位符. 用來暫時替代不確定的值.
%
被稱為格式化操作符,專門用於處理字串中的格式
- 包含 % 的字串,被稱為格式化字串
- % 和不同的字元連用,不同型別的資料需要使用不同的格式化字元
常用格式化字元 | 含義 |
---|---|
%s | 字串 |
%d | 有符號十進位制整數,%06d 表示輸出的整數顯示位數,不足的地方使用 0 補全 |
%f | 浮點數, %.2f 表示小數點後只顯示兩位 |
%% | 輸出% |
# 定義名字、年齡、工資變數
name = '司馬二狗'
age = 30
salary = 19988.78
# 格式化字串
format_string = '我的名字是%s, 我的年齡是%d, 我的工資是%.2f' % (name, age, salary)
# 輸出格式化後的字串
print(format_string)
- 格式化輸出練習
- 定義字串變數 name ,輸出我的名字叫小明,請多多關照!
- 定義整數變數 student_no ,輸出我的學號是 000001
- 定義小數 price 、 weight 、 money ,輸出蘋果單價 9.00 元/斤,購買了 5.00 斤,需要支付 45.00
print("我的名字叫 %s,請多多關照!" % name)
print("我的學號是 %06d" % student_no)
print("蘋果單價 %.02f 元/斤,購買 %.02f 斤,需要支付 %.02f 元" % (price, weight, money))
2.2.4.2 input 函式使用
input 函式主要用於從鍵盤獲取資料. 但是需要注意的是, 無論我們輸入的資料是小數、整數、還是字串, 該函式統統當做字串型別來獲取.
# 獲得鍵盤輸入
your_name = input('請輸入您的名字:')
# 輸出內容
print(your_name)
課堂練習-個人名片
- 在控制檯依次提示使用者輸入:姓名、公司、職位、電話、郵箱
- 按照以下格式輸出:
**************************************************
公司名稱
姓名 (職位)
電話:電話
郵箱:郵箱
**************************************************
實現程式碼:
name = input('請輸入姓名:')
company = input("請輸入公司:")
title = input("請輸入職位:")
phone = input("請輸入電話:")
email = input("請輸入郵箱:")
print("*" * 50 )
print(company)
print()
print("%s (%s)" % (name, title))
print()
print("電話:%s" % phone)
print("郵箱:%s" % email)
print("*" * 50 )
2.2.6 變數的型別轉換
變數型別轉換就是將變數的型別由一種型別轉換為另外一種型別, 例如將變數從數字型別轉換為字串型別.
由於各種原因, 我們在拿到資料之後, 資料的型別和我們的預期不相符, 導致我們無法進行相關的計算(資料型別決定了資料之間的運算規則). 此時我們需要先將資料的型別轉換為我們預期的型別, 再進行計算.
我們下面通過一個案例, 來理解型別轉換的作用.
我們現在完成一個計算器案例, 要求使用者輸入左運算元和右運算元, 並對兩個數進行加法計算,輸出計算結果.
# 輸入左運算元
left_number = input('請輸入一個數字:')
# 輸入有運算元
right_number = input('請輸入一個數字:')
# 對兩個數進行加法計算
result = left_number + right_number
# 輸出計算結果
print('計算結果是:', result)
執行結果可能不是我們的預期, 因為 input 接收的任何資料都當做了 str 型別來處理. 此時如果想要進行數值運算, 就必須將字串轉換為數字型別, 再進行運算.因為型別不同,運算規則不同.
我們可以使用以下函式完成變數型別的轉換:
1. int(val), 將變數 val 轉換為 int 型別.
2. float(val), 將變數 val 轉換為 float 型別.
3. str(val), 將變數 val
程式碼修改如下:
# 輸入左運算元
left_number = input('請輸入一個數字:')
# 輸入有運算元
right_number = input('請輸入一個數字:')
# 將字串型別變數轉換為數字型別
left_number_int = int(left_number)
right_number_int = int(right_number)
# 對兩個數進行加法計算
result = left_number_int + right_number_int
# 輸出計算結果
print('計算結果是:', result)
2.2.7 小結
-
變數是在程式執行過程中臨時儲存所需要的資料.
-
變數的名字規則.
2.1 識別符號由字母、下劃線和數字組成,且數字不能開頭.
2.2 python中的識別符號是區分大小寫的.
2.3 變數名一般用小寫加下劃線組成.
2.4 不能和關鍵字和已有的名字衝突.
-
變數的型別決定了變數之間的運算規則.
3.1 字串和字串只能進行加法運算, 拼接字串.
3.2 數字和數字之間可以進行所有的數學運算.
3.3 數字和字串之間只能進行乘法運算, 作用是複製指定次數字符串.
-
Python常見的變數型別有: 數字型別、字串型別、布林型別.
-
Python中的輸入和輸出分為: 標準輸入和輸出、檔案輸入和輸出、網路輸入和輸出.
-
print 是標準輸出函式, 用於向螢幕列印資料.
-
input 是標準輸入函式, 用於獲得鍵盤輸入的資料.
-
在某些情況下, 我們拿到的資料並不是我們預期型別, 此時就需要我們將該資料從一種型別轉換成我們預期的型別, 以便於完成計算. 需要注意的是, 進行型別轉換的前提是該型別的資料能夠轉換為預期型別.
2.3 分支語句
2.3.1 BUG
BUG 原意為臭蟲,在計算機領域,指導致程式不能正常執行,或者執行結果不是預期的錯誤. BUG是程式設計師在開發時非常常見的,初學者常見錯誤的原因包括:
- 手誤.
- 對技術點理解不足.
- 業務思路不熟練.
在學習語言時,不僅要學會語法,還要學會如何認識和解決錯誤的方法. 每一個程式設計師都必備的能力:
- 編碼能力.
- 解決錯誤能力.
2.3.2 IF分支語句
先看一個系統登入的案例:
# 請輸入您的使用者名稱
username = input('請輸入您的使用者名稱: ')
# 請輸入您的密碼
password = input('請輸入您的密碼: ')
# 列印歡迎資訊
print('歡迎 %s 登陸系統' % username)
以上的程式在執行過程中, 無論你輸入的是什麼, 都顯示出來歡迎登入系統的資訊提示. 實際上, "歡迎登入系統" 這個提示資訊是否要打印出來, 取決於使用者名稱和密碼是否正確, 也就是說程式碼要有選擇性的去執行, 而不是最開始無論你寫了多少行程式碼, 都會執行.
2.3.2.1 IF分支語句
1 單個分支語法格式:
if 條件一:
執行一行或多行特定程式碼
如果條件成立則執行 if 下面的程式碼, 不成立則不會執行.
案例程式碼:
a = 10
if a > 5:
print('a > 5')
2 兩個分支語法格式
if 條件一:
執行一行或多行特定程式碼
elif 條件二:
執行一行或多行特定程式碼
如果 if 條件成立, 則執行 if 下面的程式碼如果 elif 條件成立, 則執行 elif 下面的程式碼如果 if elif 條件同時成立, 則執行第一個滿足條件的分支
案例程式碼:
name = 'Obama'
if name == 'Obama':
print('i am obama')
elif name == 'trump':
print('i am trump')
if 條件一:
執行一行或多行特定程式碼
else :
執行一行或多行特定程式碼
如果 if 條件成立, 則執行 if 下面的程式碼如果 if 條件不成立, 則執行 else 下面的程式碼 if 和 else 程式碼必定會執行其中一個。
案例程式碼:
name = 'Obama'
if name == 'Obama':
print('i am obama')
else :
print('i am others')
注意:else後面不需要寫條件
3 多個分支語法格式
if 條件一:
執行一行或多行特定程式碼
elif 條件二:
執行一行或多行特定程式碼
elif 條件三:
執行一行或多行特定程式碼
elif 條件四:
執行一行或多行特定程式碼
如果 if 條件成立, 則執行 if 下面的程式碼。如果 elif 條件成立, 則執行 elif 下面的程式碼。如果 if elif 條件同時成立, 則執行第一個滿足條件的分支。
案例程式碼:
day = input('請輸入1-7的數字:')
if day == '1' :
print('今天是星期一')
elif day == '2' :
print('今天是星期二')
elif day == '3' :
print('今天是星期三')
elif day == '4' :
print('今天是星期四')
elif day == '5' :
print('今天是星期五')
elif day == '6' :
print('今天是星期六')
elif day == '7' :
print('今天是星期日')
if 條件一:
執行一行或多行特定程式碼
elif 條件二:
執行一行或多行特定程式碼
elif 條件三:
執行一行或多行特定程式碼
else :
執行一行或多行特定程式碼
如果 if 條件成立, 則執行 if 下面的程式碼.如果 elif 條件成立, 則執行 elif 下面的程式碼.如果 if elif 都不滿足條件, 則執行else 下面的程式碼.
day = input('請輸入1-7的數字:')
if day == '1' :
print('今天是星期一')
elif day == '2' :
print('今天是星期二')
elif day == '3' :
print('今天是星期三')
elif day == '4' :
print('今天是星期四')
elif day == '5' :
print('今天是星期五')
elif day == '6' :
print('今天是星期六')
elif day == '7' :
print('今天是星期日')
else:
print('無法確定是星期幾')
2.3.2.2 if條件成立
成立則表示結果為真(True), 不成立則表示結果為假(False).
運算子 | 描述 |
---|---|
== | 檢查兩個運算元的值是否相等,如果是,則條件成立,返回 True |
!= | 檢查兩個運算元的值是否不相等,如果是,則條件成立,返回 True |
> | 檢查左運算元的值是否大於右運算元的值,如果是,則條件成立,返回 True |
< | 檢查左運算元的值是否小於右運算元的值,如果是,則條件成立,返回 True |
>= | 檢查左運算元的值是否大於或等於右運算元的值,如果是,則條件成立,返回 True |
<= | 檢查左運算元的值是否小於或等於右運算元的值,如果是,則條件成立,返回 True |
登入案例的程式碼可修改為:
# 請輸入您的使用者名稱
username = input('請輸入您的使用者名稱:')
# 請輸入您的密碼
password = input('請輸入您的密碼:')
# 判斷密碼是否正確
if username == 'admin':
# 再判斷密碼是否合法
if password == 'admin':
# 列印歡迎資訊
print('歡迎 %s 登入系統!' % username)
else :
print('使用者名稱或者密碼不正確!')
else :
print('使用者名稱或者密碼不正確')
多個條件之間的關係
我們可以將多個條件並列寫在 if 後面, 此時需要表示多個條件之間的關係, 需要邏輯運算子.
運算子 | 邏輯表示式 | 描述 |
---|---|---|
and | x and y | 只有x和y的值都為True,才會返回True,否則只要x或者y有一個指為False,就返回False |
or | x or y | 只要 x 或者 y 有一個值為 True,就返回 True,只有 x 和 y 的值都為 False,才會返回 False |
not | not x | 如果 x 為 True,返回 False,如果 x 為 False,返回 True |
我們繼續修改上面程式碼為:
# 請輸入您的使用者名稱
username = input('請輸入您的使用者名稱:')
# 請輸入您的密碼
password = input('請輸入您的密碼:')
# 判斷密碼是否正確
if username == 'admin' and password == 'admin':
# 列印歡迎資訊
print('歡迎 %s 登入系統!' % username)
else :
print('使用者名稱或者密碼不正確')
2.3.3 練習-猜拳遊戲
import random
user_quan = int(input('請出拳石頭(0)、剪刀(1)、布(2):'))
computer_quan = random.randint(0, 2)
if (user_quan == 0 and computer_quan == 1) or \
(user_quan == 1 and computer_quan == 2) or \
(user_quan == 2 and computer_quan == 0):
print('您贏了!')
elif user_quan == computer_quan:
print('平局!')
else :
print('您輸了!')
2.3.4 小結
-
if 語句的作用可以實現選擇執行某些特定程式碼.
-
if 語句的條件結果為真, 則會執行對應分支下的程式碼.
-
if 條件的運算子包含比較關係運算符、邏輯關係運算符.
i. 比較關係運算符用於構建單個條件.
ii. 邏輯關係運算符可用於表示多個條件之間的關係. 5.1 and: 多個條件都為真, 則整個條件結果為真. 5.2 or:多個條件中有一個條件為真, 則整個條件結果為真. 5.3 not: 對條件取反, 如果條件為真, 則結果為假, 反之則反.
-
BUG 在程式中不可避免, 要學會解決錯誤. 多積累.
2.4 迴圈語句
2.4.1 while 迴圈
我們的猜拳遊戲只能玩一次, 然後就需要重新啟動程式. 我們在玩遊戲時,並不會每次玩都需要重新啟動程式.
Python 提供了 while 迴圈語法用於支援特定程式碼重複執行.
1 while 迴圈的語法格式
while 條件:
重複執行的一行或多行程式碼
Python 每次會判斷 while 關鍵字後面的條件是否為真, 如果為真, 則執行 while 下面的一行或多行程式碼, 直到不滿足條件, 迴圈執行結束.
注意: 如果條件永遠滿足, 則意味著迴圈永遠會被執行, 叫做死迴圈, 這是無意義的.
2 while 迴圈課堂練習
計算1-100之間的累加和:
i = 1
sum = 0
while i <= 100:
sum += i
i += 1
print('1~100的累加和為:%d' % sum)
2.4.2 break 和 continue
我們下面實現一個需求, 使用者輸入名字, 並顯示名字, 當輸入 stop 時, 停止輸入.
name = ''
while name != 'stop':
name = input('請輸入一個名字(stop停止輸入):')
if name != 'stop':
print(name)
我們可以在迴圈體內部使用 IF 語句配合 break 關鍵字來實現. 那麼 break 是什麼意思? 當迴圈體執行到 break 語句時就會馬上退出迴圈.
while True:
name = input('請輸入一個名字(stop停止輸入):')
if name == 'stop'
# 推出迴圈
break
else
print(name)
如果 while 條件比較簡單的話, 我們可以將迴圈退出條件寫到 while 後面, 但有時一個迴圈退出的條件比較複雜, 也就是有多個條件, 寫到 while 後面會增加閱讀理解難度. 我們可以將條件寫到迴圈內部, 會更加容易理解.
現在我的需求出來了, 我在做累加的時候, 希望碰到偶數的時候不累加. 那麼該如何實現呢?
解決這個問題, 我們只需要讓迴圈體的變數 i 等於偶數時, 跳過那一次迴圈, 並不退出迴圈, 就可以實現我們想要的需求了.
i = 1
sum = 0
while i < 100:
if i % 2 == 0
# 一定要加上這一句,否則會進入死迴圈
i += 1
# 如果i為偶數則跳過薰昏
continue
sum += i
i += 1
print('1~100的累積和為:%d' % sum)
2.4.3 小結
- while迴圈用於特定程式碼重複執行.
- break 語句用於退出迴圈.
- continue 語句可以終止當前次迴圈.
- while 迴圈要避免死迴圈出現.
2.5 函式
2.5.1 函式的作用
請問: 我家裡種地需要鋤頭, 我是每次去鋤地時重新做一把鋤頭, 還是提前做好一把鋤頭, 需要時直接拿來用?
很顯然, 每次重新做都是重複勞動, 浪費時間. 所以我們選擇提前做好一把鋤頭, 每次直接拿來用, 這裡面就是一種複用的思想. 程式設計思想來源於生活, 所以在程式中也有複用的思想, 只不過複用的是程式碼.
我們的程式碼是完成某些固定任務, 如果需要頻繁解決這個問題, 那麼解決這個問題的程式碼就可以提前寫好, 需要解決該問題時, 直接拿來用.
例如: 我在程式碼檔案的多個地方都需要計算1-100累加和這個功能, 那麼怎麼解決這個問題呢?
最簡單的方式就是將咱們之前的程式碼拷貝到需要這個功能的地方. 這麼寫也很明顯帶來一個問題, 如果這個累加和的功能實現改變了, 意味著所有地方都需要修改, 增加了程式碼的維護量.
怎麼解決呢? 通過將這個功能封裝成一個單獨的功能程式碼塊, 只要需要該功能, 直接使用該功能程式碼塊, 這個功能程式碼塊我們也叫做函式.
簡言之, 函式的作用就是將常用的程式碼封裝起來,便於以後使用.
2.5.2 函式語法格式
在Python中,函式使用def關鍵字來定義,包含函式的名字(功能的名字),函式的實現(實現功能的程式碼).
函式的行為分為: 函式定義和函式呼叫.
1. 函式定義是實現函式功能的過程.
2. 函式呼叫是使用功能.
注意: 函式不呼叫是不會自動執行的.
def 函式名():
一行或多行程式碼
那麼1-100這個功能我們就可以寫成這樣的一個函式(功能程式碼塊).
def my_sum():
i = 1
s = 0
while i <= 100:
s += i
i += 1
print("1-100的累積和為:%d" % s)
# 函式呼叫
my_sum()
當使用該功能時直接呼叫該函式即可.
2.5.2.1 函式的引數
我們可以將我們要開始和結束數字傳遞給函式, 讓函式按照我們傳遞的引數來計算.
def my_sum(start, end):
my_start = start
my_end = end
my_sum = 0
while my_start <= my_end:
my_sum += my_start
my_start += 1
print("%d-%d的累積和為:%d" % (start, end, my_sum))
# 函式呼叫
my_sum(2, 50)
函式引數的作用就是讓函式依據我們給定的值來進行運算. 這樣可以增強函式的通用性. 函式可以有多個引數.
例如: 我們想要編寫一個具有加法功能函式,很顯然需要兩個引數.
def my_add(num1, num2):
result = num1 + num2
print('num1 + num2 = ', result)
my_add(10, 20)
我們在呼叫函式時傳遞的真實資料叫做實參, 函式引數叫做形參, 形參只是代表真實傳遞的數值.
多個函式引數在傳遞時是從左向右傳遞的. 當然, 在 Python 中我們也可以指定某個值給那個形參.
def my_add(num1, num2):
result = num1 + num2
print('num1 + num2 =', result)
my_add(num1=10, num2=20)
my_add(num2=20, num1=10)
# 1. 按照從左向右的順序傳遞叫做位置引數.
# 2. 按照形參名字傳遞叫做關鍵字引數.
能否在呼叫函式時既傳遞位置引數, 又傳遞關鍵字引數呢?
def my_add(num1, num2, num3, num4):
result = num1 + num2 + num3 + num4
return result
my_add(100, 200, 300, num2=10)
可以, 只需要保證位置引數在關鍵字引數之前即可.
2.5.2.2 函式的返回值
請思考下面兩個問題:
-
現在我們的函式在計算完結果之後, 把結果放到哪裡了?
-
我的程式需要繼續使用函式的結計算果來進行下一步計算, 該怎麼辦?
使用 return 語句將函式的執行結果返回給函式的呼叫者.
def my_add(num1, num2):
result = num1 + num2
return result
# 使用一個變數儲存函式執行的結果
my_add_result = my_add(10, 20)
# 使用結果進行下一步計算
finish_result = my_add_result + 100
# 輸出最終結果
print('最終結果:', finish_result)
print 只負責將內容輸出到螢幕顯示. 而 return 會將函式計算結果, 返回給函式的呼叫者.
比如: 函式類似於一個工廠, 我們將工廠生產所需要的材料通過引數的形式傳遞給工廠, 工廠使用我們傳遞的材料生 產出產品.
print 相當於生產完產品後, 說了一句 "產品生產完畢", 但是並不會把產品給使用者.
而 return 相當於生產完產品之後, 並將產品交到使用者手裡. 那麼使用者就需要用一個籃子來裝產品(用變數來儲存函式 的返回值). 當然, 雖然工廠將產品給了使用者, 使用者也可以不要(忽略函式的返回值).
關於 return 注意下以下幾點.
-
只要函式執行碰到 return 就會停止執行.
-
函式中可以編寫多個 return, 但有且只有一個 return 會執行.
-
return 後面可以跟上要返回的值, 也單獨使用相當於 return None.
-
break 用在迴圈中, 用來終止迴圈執行. return 用在函式中, 用來終止函式執行.
2.5.2.3 區域性變數和全域性變數
-
全域性變數: 在函式外部定義的變數. 全域性指的是該變數在當前 python 檔案範圍內是可見的. 全域性變數可以被當前 python 檔案內的所有函式直接使用.
-
區域性變數: 在函式內部定義的變數. 該變數只能在定義的函式內部使用.
# 定義全域性變數
g_val = 100
# 在函式內部可以訪問全域性變數
def my_function1():
print(g_val)
# 在函式內部定義區域性變數 my_val
def my_function2():
my_val = 100
# 嘗試輸出 my_function2 函式中定義的區域性變數
def my_function3():
print(my_val)
# 函式呼叫
my_function1()
my_function2()
my_function3()
如果區域性變數和全域性變數命名衝突, Python 直譯器會怎麼做?
total_value = 100
def my_function():
total_value = 200
print('total_value:', total_value)
my_function()
Python 直譯器會在函式內部搜尋變數 total_value, 如果找到了就直接使用, 如果找不到則到全域性範圍內搜尋.
2.5.2.4 函式的預設引數(預設引數)
預設引數指的是當函式呼叫中省略了實參時預設使用的值.
預設引數的語法與使用:
-
在函式宣告或定義時, 直接對引數賦值. 這就是設定形參的預設引數.
-
在函式呼叫時, 省略部分或全部的引數. 這時可以用預設引數來代替.
def my_function(a, b=20, c=30):
return a+b+c
my_function(10)
my_function(10, 100)
my_function(10, 100, 1000)
注意: 帶有預設值的引數一定要位於引數列表的最後面.
2.5.3 函式文件及作用
函式也需要添加註釋, 方便函式功能、引數以及返回值的含義能夠被呼叫者知悉. 但普通的單行多行註釋, 需 要檢視函式定義時才能看到, 有沒有一種方式能夠在呼叫時快捷檢視函式相關資訊?
DocString 是一個重要的工具, 因為它能幫助你的程式文件更加簡單易懂.
# 單行函式文件字串
def my_function(param):
"""函式做了什麼事, 返回什麼結果."""
return param + 10
# 多行函式文件字串
def my_add(num1, num2):
"""計算兩個整數的和.
:param int num1: 加法運算的左運算元
:param int num2: 加法運算的右運算元
:return 返回兩個運算元相加的結果
"""
result = num1 + num2
return result
我們可以通過 ctrl + q 快捷鍵可以檢視函式資訊, 也可以通過 help() 函式來檢視函式資訊.
2.5.4 單一職責原則
單一職責原則說的是一個函式只負責一個事情.這是因為, 如果一個函式承擔的職責過多, 就等於把這些職責混合在 一起, 一個職責的變化可能會影響其它職責的能力.
1.簡稱 單一職責原則的英文名稱是Single Responsibility Principle, 簡稱RSP.
2.定義 就一個函式而言, 應該僅有一個引起它變化的原因, 簡單的說, 一個函式中應該是一組相關性很高的的封裝. 即一個類只負責一項職責, 而不應該同時負責多個職責.
3.問題 比如 C 函式負責兩個不同的職責 D1 和 D2. D1 功能需求發生變化時, 更改 C 函式, 有可能使原本正常執行 的 D2 發生錯誤, 程式碼耦合性太高, 較複雜.
4.解決 把功能獨立出來, 讓它們滿足單一職責原則. 比如建立兩個函式 C1 和 C2, C1 完成功能 D1, C2 完成功能 D2. 任何一個功能出現問題都不會造成另一個功能出問題.
2.5.5 小結
-
函式是實現程式碼複用的一種技術, 可以減少程式碼冗餘.
-
函式定義不會執行程式碼, 函式呼叫會執行程式碼.
-
函式使用 def 來定義, 函式呼叫時候使用 "函式名(引數...)".
-
函式呼叫時, 如果位置引數和關鍵字引數並存, 位置引數必須在關鍵字引數前面.
-
函式的引數叫做形參, 呼叫函式時傳遞的數值叫做實參.
-
函式內部定義的變數叫做區域性變數, 函式外部定義的變數叫做全域性變數. 6.1 區域性變數只能在函式內部使用, 函 數外無法使用. 6.2 全域性變數可以在當前 python 檔案定義的所有函式中訪問. 6.3 全域性範圍指的是整個 Python 檔案範圍.
-
函式文件的作用解釋說明函式, 並可以通過 ctrl + q 或者 help() 函式快速查閱.
-
函式的編寫要遵循的單一職責原則, 即一個函式只負責一個事情.
-
return 用於將函式的計算結果返回給函式的呼叫者, 使用時需要注意以下幾點: 9.1 只要函式執行碰到 return 就 會停止執行. 9.2 函式中可以編寫多個 return, 但有且只有一個 return 會執行. 9.3 return 後面可以跟上要返回的 值, 也單獨使用相當於 return None. 9.4 break 用在迴圈中, 用來終止迴圈執行. return 用在函式中, 用來終止函式執行.
3 容器
我們根據不同容器的特性, 將常用容器分為序列式容器和非序列式容器.
-
序列式容器中的元素在存放時都是連續存放的, 也就是在序列式容器中, 除了第一個元素的前面沒有元素, 最後一 個元素的後面沒有元素, 其他所有的元素前後都有一個元素. 包括字串、列表、元組.
-
非序列式容器在儲存元素時不是連續存放的, 容器中的任何一個元素前後都可能沒有元素. 包括字典、集合.
- 序列式容器支援根據索引(下標)訪問元素, 而非序列式容器不支援索引(下標)的方式訪問元素.
- 序列式容器支援切片操作, 而非序列式容器不支援切片操作.
在序列式容器中, 會給每一個元素賦予一個編號, 該編號從 0 開始計算. 第一個元素的索引就為 0, 第二個元素的索引就為 1, 以此類推, 支援索引的容器可以使用 0 1 ... 來獲得某個位置的元素.
通過索引可以獲取序列式容器中的某個元素, 切片語法主要用於獲得一個指定索引區間的多個元素, 例如獲取從索引值為 0 到索引值為 5 之間的所有元素.
容器用來儲存多個元素, 針對元素的操作提供了一些操作方法, 比如新增一個元素、刪除一個元素、修改一個元素、 對容器中的元素排序等等.
學習容器型別就是在學習容器的特點、以及容器對元素的操作.
上面所說的 "方法", 就是我們所說所學的函式, 本質上 "方法"和"函式"指的是同一個東西, 只不過我們將某個型別專屬的一些函式叫做方法.
3.1 字串
3.1.1 字串語法格式
我們知道資料是有型別的, 現實生活中很多資料都僅僅是一個字元序列, 計算機如何表示字元序列的資訊, 使用字串型別.
如何定義字串?
-
字串使用一對單引號來定義.
-
字串使用一對雙引號來定義.
-
字串使用一對三引號來定義.
一般我們在定義字串時候, 使用兩個單引號或者兩個雙引號, 很少使用三引號.
3.1.2 字串操作
3.1.2.1 字串遍歷
字串屬於序列式容器, 支援依據索引的操作.
我們可以使用 while 迴圈來訪問字串容器中的每一個字元元素.
注意: 序列式容器的索引都是以 0 開始的, 並不是從 1 開始.
my_string = '我叫做司馬狗剩,我今年10歲了!'
i = 0
while i < len(my_string):
print(my_string[i], end=' ')
i += 1
Python 是一門簡單易用的語言, 對於容器的遍歷, 提供了另外一種簡單方式 - for 迴圈.
my_string = '我叫做司馬狗剩,我今年10歲了!'
for ch in my_string:
print(ch, end=' ')
3.1.2.2 字串替換
我們現在已經儲存了一首詩歌:
poetry = '遠看泰山黑乎乎, 上頭細來下頭粗. 茹把泰山倒過來, 下頭細來上頭粗.'
詩歌中的茹正確寫法應該是如, 我們需要用程式解決這個問題, 如何做?
-
查詢到錯別字茹.
-
將錯別字替換成正確的如字.
我們可使用字串的 replace 方法完成上面兩步. 該方法預設會將字串中所有指定字元或子串替換為新的字串, 我們可以指定第三個引數, 替換多少次.
poetry = '遠看泰山黑乎乎, 上頭細來下頭粗. 茹把泰山倒過來, 下頭細來上頭粗. 茹'
# 將所有的 '茹' 替換為 '如'
right_poetry = poetry.replace('茹', '如')
# 只替換第一次出現的 '茹'
right_poetry = poetry.replace('茹', '如', 1)
3.1.2.3 字串查詢和切片
現在有一郵箱地址如下:
user_email = '[email protected]'
我們希望從郵箱地址字串中獲取使用者名稱和郵箱字尾名, 那麼這個問題如何解決?
-
由分析可知, @符號之前為使用者名稱, @符號之後的內容為郵箱字尾名.
-
首先獲得 @ 符號的位置, 從開始位置擷取到 @ 符號位置, 即可獲得使用者名稱.
-
從 @ 符號位置開始擷取到字串最後, 即可獲得郵箱字尾名.
如何獲得 @ 符號的位置?
我們可以使用字串提供的 find 方法, 該方法可返回查詢字串第一次出現的位置, 查詢字串不存在則會返回-1.
備註: find 方法預設從字串開始位置(0位置)開始查詢, 我們也可以指定從哪個位置範圍開始查詢, 設定 find 的第二個引數表示從哪個位置開始查詢, 第三個引數表示查詢結束位置.
poetry = '遠看泰山黑乎乎, 上頭細來下頭粗. 茹把泰山倒過來, 下頭細來上頭粗.'
# 從 10 位置開始查詢 '上'
position = poetry.find('上', 10, 100)
如何獲得指定範圍的字串?
字串屬於序列式容器, 可以根據索引獲得某一個字元, 也可以根據由兩個索引標識的區間獲得區間內的字元序列.
poetry = '遠看泰山黑乎乎, 上頭細來下頭粗. 茹把泰山倒過來, 下頭細來上頭粗.'
# 從0位置開始到7位置之前, 不包含7位置字元
print(poetry[0: 7])
# 起始位置不寫, 預設就是0
print(poetry[: 7])
# 從0位置開始到最後
print(poetry[9:])
# 步長, 每隔2個字元選取一個字元, 組成一個序列
print(poetry[0: 7: 2])
# 如果步長為負數, 那麼起始位置引數和結束位置引數就會反過來.
print(poetry[6:: -1])
# 位置也可以使用負數
print(poetry[-3: -1])
print(poetry[-3:])
print(poetry[::-1])
user_email = '[email protected]'
# 查詢 @ 位置
position = user_email.find('@')
# 根據 postion 擷取使用者名稱和郵箱字尾
user_name = user_email[: position]
mail_suffix = user_email[position + 1:]
另外一種解決該問題的思路.
- 先根據 @ 符號將郵箱分割成兩部分.
- 分別獲取每一部分, 即可得到使用者名稱和郵箱字尾.
user_email = '[email protected]'
# 判斷 user_email 是否有多個 @
at_count = user_email.count('@')
if at_count > 1:
print('郵箱地址不合法, 出現了多個@符號!')
else:
# 根據 @ 將字串擷取為多個部分
result = user_email.split('@')
# 輸出使用者名稱和郵箱字尾
print(result[0], result[1])
3.1.2.4 字串去除兩側空格、是否為字母
我們經常在各個網站進行會員註冊, 一般註冊的處理流程如下:
-
獲得使用者輸入的註冊使用者名稱.
-
使用者在輸入使用者名稱時, 可能在使用者名稱兩個不小心輸入多個空格. 我們需要去除使用者名稱兩側的空格.
-
判斷使用者名稱是否全部為字母(使用者名稱的組成由我們來規定, 這裡我們規定必須是字母)
-
處理完畢之後, 顯示註冊成功.
# 獲得使用者註冊使用者名稱
register_username = input('請輸入您的使用者名稱:')
# 去除使用者名稱兩側的空格
register_username = register_username.strip()
# 判斷字串是否全部為字母
if register_username.isalpha():
print('恭喜您:', register_username, '註冊成功!')
else:
print('註冊失敗!')
3.1.3 小結
-
字串一般使用兩個雙引號或兩個單引號來定義.
-
字串容器特點: 元素不能修改, 並且只能由一系列字元組成.
-
字串是序列式容器, 支援下標索引和切片操作, 索引支援正數和負數.
-
切片語法由開始索引、結束索引、步長組成, 語法格式如: my_str[start: end: step] 4.1 開始索引省略預設為0.4.2 結束索引省略預設為最後一個元素的索引的下一個索引. 4.3 步長省略預設為 1. 4.4 步長為負數時, 開始索 引就變成結束索引, 結束索引就變成開始索引. 4.5 切片的索引區間為左閉右開.
-
字串遍歷可以使用 while 迴圈, 也可以使用 for 迴圈.
-
字串的 find 方法用於查詢指定子串是否存在, 存在則返回出現的索引位置, 否則返回-1.
-
字串的 repalce 方法用於替換字串中的指定子串, 注意, 不會修改原字串. 會返回一個替換後的新字串.
-
字串的 count 方法返回指定子串出現的次數.
-
字串的 split 方法根據指定的分割字串, 將原字串分割成多個部分, 以列表形式返回.
-
字串的 strip 方法去除字串兩側空格.
-
字串的 isalpha 方法判斷字串是否全部為字母組成.
3.2 列表
3.2.1 列表語法格式
字串容器中存放的元素只能是字元序列, 並且字串容器中的元素不能修改, 如果需要儲存的資料並非單一 型別, 並且需要頻繁修改, 如何解決?
我們可以使用列表容器型別, 列表中儲存的元素可以是多種資料型別, 甚至儲存的資料型別都不一樣, 並且列表支援對元素的修改、刪除等操作.
列表也是一個序列式容器, 同樣支援索引和切片語法.
# 建立空列表
my_list = []
# 建立帶有元素的列表
my_list = [10, 20, 30]
# 通過索引來訪問列表中元素
print(my_list[0])
# 也可以通過索引來修改元素
my_list[0] = 100
# 通過切片語法獲得區間元素
print(my_list[1:])
# 列表可儲存不同型別的資料
my_list = ['John', 18, True]
# 列表中也可儲存列表
my_list = [[10, 20], [30, 40], [50, 60]]
注意: 列表中支援儲存不同型別的資料, 如果有沒有特殊需求, 建議儲存相同型別資料. 這樣可以對資料應用統一的操作.
3.2.2 列表操作
3.2.2.1 列表遍歷
my_list = [1, 2, 3, 4, 5]
i = 0
while i < len(my_list):
print(my_list[i], end=' ')
i += 1
我們也可以用 for 迴圈來簡化列表的遍歷操作.
my_list = [1, 2, 3, 4, 5]
for val in my_list:
print(val, end=' ')
3.2.2.2 列表查詢和修改
已知: 列表中包含 5 個元素, 分別為: 10、20、30、40、50. 需要將列表中 40 這個元素替換成 100, 如何實現?
-
列表不存在類似字串 replace 的方法.
-
查詢 40 這個元素在列表中的索引位
-
根據索引位置修改元素為 100.
index 方法可以根據值查詢, 查詢到返回該值元素所在的位置, 查詢失敗會報錯, 程式終止. 我們可以先使用 count 方法可以統計值出現的次數, 如果不為0, 再使用 index 方法.
my_list = [10, 20, 30, 40, 50]
# 要修改的值
old_value = 40
# 更新的新值
new_value = 100
# 判斷要修改的值是否存在
if my_list.count(old_value):
# 獲得指定值的位置
position = my_list.index(old_value)
# 根據值來修改元素
my_list[position] = new_value
print(my_list)
如果我們只是關心值是否存在, 而並不關心出現多少次, 可以使用 in 或者 not in 運算子.
- in 可以判斷元素是否存在, 存在返回 True, 不存在返回 False.
- not in 可以判斷元素是否不存在, 不存在返回 True, 存在返回 False.
以上程式碼可修改為:
my_list = [10, 20, 30, 40, 50]
# 要修改的值
old_value = 40
# 更新的新值
new_value = 100
# 判斷要修改的值是否存在
if old_value in my_list:
# 獲得指定值的位置
position = my_list.index(old_value)
# 根據值來修改元素
my_list[position] = new_value
print(my_list)
3.2.2.3 列表的插入和刪除元素
列表是一個容器, 我們可以向容器中新增和刪除元素.
插入元素分為:
- 插入單一元素. 1.1 尾插. 1.2 指定位置插入.
- 插入一個列表(多個元素).
Python 提供了 append 方法, 用於向列表尾部新增元素, insert 方法用於向列表指定的索引位置插入元素, extend 方法用於將另外一個列表中的所有元素追加到當前列表的尾部.
刪除分為兩種:
-
根據值刪除, 使用 remove 方法. 該方法只能刪除第一次出現的值.
-
根據索引刪除, 使用 pop 方法, 該方法不傳遞索引時預設刪除最後一個元素, 傳遞索引則根據索引刪除元素.
# 插入元素分為兩種: 尾部插入 指定位置插入
# 建立空列表
my_list = []
# 向列表中新增元素
my_list.append(10)
my_list.append('Obama')
# 在指定位置插入元素
my_list.insert(1, 20)
# 輸出內容
print(my_list)
# 建立新的列表
new_list = [100, 200, 300]
# 合併兩個列表
my_list.extend(new_list)
print(my_list)
# 刪除分為兩種: 根據值刪除, 根據位置(索引)刪除
my_list = [10, 20, 30, 20]
# 根據索引刪除
my_list.pop(2)
print(my_list)
# 根據值刪除
my_list.remove(20)
print(my_list)
# 刪除所有元素
my_list.clear()
# 顯示列表中還剩下多少元素
print(len(my_list))
3.2.2.4 列表元素排序
排序指的是記錄按照要求排列. 排序演算法在很多領域得到相當地重視.
列表提供了相關方法來對列表中的元素進行排序. 分別是:
-
將列表中的元反轉.
-
列表中的元素升序(從小到大)、降序排列(從大到小).
import random
my_list = []
# 產生一個包含10個隨機數的列表
i = 0
while i < 10:
random_number = random.randint(1, 100)
my_list.append(random_number)
i += 1
# 列印列表中的元素
print('my_list:', my_list)
# 對列表中的反轉
y_list.reverse()
# 列印列表中的元素
print('my_list:', my_list)
# 對列表中的元素排序, 預設升序
my_list.sort()
print('my_list:', my_list)
# 對列表中的元素排序, 降序排列
my_list.sort(reverse=True)
print('my_list:', my_list)
3.2.2.5 列表練習
一個學校, 有3個辦公室, 現在有 8 位老師等待工位的分配, 請編寫程式, 完成隨機的分配.
思路分析如下:
-
待分配的 8 位老師需要儲存, 我們可以用列表來暫時儲存 8 位老師.
-
一個學校中包含了多個辦公室, 學校可用列表來表示, 學校中又包含了多個辦公室, 每個辦公室裡可能有多個老 師, 辦公室仍然可用列表來表示.
-
從待分配老師列表中取出資料, 隨機產生辦公室編號, 將該老師分配到該辦公室.
-
列印各個辦公室中的老師列表.
import random
# 定義一個列表用來儲存8位老師的名字
teacher_list = []
i = 0
while i < 8:
teacher_name = '老師' + str(i + 1)
teacher_list.append(teacher_name)
i += 1
# 定義學校幷包含3個辦公室
school = [[], [], []]
# 獲取每個老師並隨機分配辦公室
for teacher in teacher_list:
office_nunmber = random.randint(0, 2)
school[office_nunmber].append(teacher)
# 列印各個辦公室的老師列表
for office in school:
for teacher in office:
print("%s" % teacher, end=' ')
print('\n' + '*' * 20)
3.2.3 小結
-
列表一般使用一對中括號 [ ] 來定義.
-
列表容器的特點: 可以儲存任意型別的資料, 並且元素可以修改.
-
列表中儲存的元素型別可不相同, 但建議儲存同樣的型別.
-
列表是序列式容器, 支援下標索引和切片操作.
-
列表遍歷可以使用 while 迴圈, 也可以使用 for 迴圈.
-
列表可通過 in 或 not in 運算子來判斷是否存在某個元素.
-
列表的 append 方法用於向列表尾部新增元素.
-
列表的 insert 方法用於向列表指定索引位置新增元素.
-
列表的 extend 方法用於將一個列表中所有元素新增到當前列表的尾部.
-
列表的 pop 方法預設刪除尾部元素, 如果設定索引引數, 可刪除該索引位置的元素.
-
列表的 reverse 方法可以將列表中元素逆序.
-
列表的 sort 方法可以將列表中的元素升序或者降序排列.
3.3 元組
3.3.1 元組語法和方法
Python的元組與列表類似, 不同之處在於元組的元素不能修改. 元組使用小括號來定義, 列表使用方括號來定義.
由於元組不支援修改, 所以元組只支援遍歷、查詢操作.
元組同樣屬於序列式容器, 支援索引和切片語法.
-
查詢元素: count 、 index
-
遍歷操作: while、for
# 定義元組
my_tuple = (10, 20, 30)
my_tuple = ((10, 20, 30), (100, 200, 300))
# 遍歷
for ele in my_tuple:
for val in ele:
print(val)
# 查詢
my_tuple = (10, 20, 30)
# 判斷元素是否存在
if my_tuple.count(20) > 0:
index = my_tuple.index(20)
print('元素的位置:', index)
if 20 in my_tuple:
index = my_tuple.index(20)
print('元素的位置:', index)
注意: 如果定義的元素中只有一個元素, 需要額外新增一個逗號在元素後.
my_tuple = (10,)
my_tuple = ((10, 20, 30), )
my_tuple = ((10, ), )
3.3.2 小結
-
元組使用一對小括號來定義, 在定義之後不允許對元素進行修改.
-
元組中只有一個元素時, 需在最尾部新增一個逗號.
-
元組是序列式容器, 支援索引、切片操作.
-
元組比列表更節省空間.
3.4 字典
在列表中根據某個關鍵字去查詢資料效率較低. 為了解決該方面的問題, Python 提供了字典 這種容器型別, 字典中儲存的每一個元素都是鍵值對, 並且在字典中根據鍵(關鍵字)去查詢某個元素的效率非常高.
為了實現高的查詢效率, 字典被實現成了一種非序列式容器, 也就導致字典無法根據索引獲得元素, 同樣也不支援切片操作.
3.4.1 字典語法格式
字典是另一種可儲存任意型別物件. 字典中的每一個元素都是一個 "鍵值對", 鍵值之間用冒號(:)分割, 每個字典元素 (鍵值對)之間用逗號(,)分割, 整個字典包括在花括號 {} 中, 格式如下所示:
my_dict = {key1: value1, key2: value2, key3: value3}
字典鍵和值的特點:
-
鍵一般是唯一的, 如果重複,最後的一個鍵值對會替換前面的, 鍵的型別一般情況下使用字串、數字型別.
-
值 不需要唯一, 可以為任何的資料型別.
3.4.2 字典操作
3.4.2.1 訪問元素
字典中根據鍵獲得值的操作, Python 提供了兩種方式:
-
直接通過鍵來獲得, 但當鍵不存在時, 會丟擲錯誤.
-
通過 get 方法來根據鍵獲得值, 如果鍵不存在則會返回 None, 該返回預設值也可自定義.
person = {'name': 'Obama', 'age': 18, 'sex': '男'}
# 如果 key 不存在會報錯
print(person['name'])
# 如果 key 不存在可設定預設值
print(person.get('gender', 'default'))
3.4.2.2 新增和修改元素
在字典中修改元素, 直接通過鍵來修改即可. 這時需要注意, 如果鍵不存在, 預設為新增元素操作, 只有鍵存在時, 才為修改操作.
person = {'name': 'Obama', 'age': 18, 'sex': '男'}
# 如果 key 不存在則為新增新元素
person['salay'] = 12000
# 如果 key 存在則為修改元素
person['age'] = 20
3.4.2.3 刪除元素
Python 中字典中元素的刪除, 需要根據鍵來進行, 我們可以使用 pop 方法根據 key 來刪除字典中的元素.
person = {'name': 'Obama', 'age': 18, 'sex': '男'}
# 刪除某個元素
person.pop('name')
# 清空字典
person.clear()
3.4.2.4 遍歷元素
由於字典是非序列式容器, 無法通過逐個獲取元素, 所以遍歷字典的方式就是先將字典轉換成類似列表的形式, 再對其進行遍歷. 在獲得字典的列表時, 我們有以下三個方案:
-
獲得字典鍵的列表, 通過字典的 keys 方法.
-
獲得字典值的列表, 通過字典的 values 方法.
-
獲得字典的鍵值對列表, 通過字典的 items 方法.
person = {'name': 'Obama', 'age': 18, 'sex': '男'}
# 獲得字典的值列表
print(person.values())
# 獲得字典的鍵列表
print(person.keys())
# 獲得字典的鍵值對列表
print(list(person.items()))
for key, value in person.items():
print(key, value)
3.4.3 小結
-
字典通過一對花括號 "{}" 來定義, 每一個元素都是一個鍵值對.
-
字典不支援索引、切片操作.
-
字典根據鍵查詢元素的效率非常高.
-
字典的鍵一般情況下是數字、字串等, 鍵必須唯一不重複.
-
字典的值可以重複, 任意型別.
-
for 迴圈無法直接遍歷字典, 需要先將字典轉換為類似列表那樣能夠被迭代的型別.
-
字典的 get 方法可以根據鍵獲得值, 如果鍵不存在返回預設值.
-
字典的 pop 方法可以根據鍵來刪除字典中某個元素.
-
字典的 clear 方法可用來清空字典.
-
字典的 keys 方法可以返回一個由字典的鍵組成的列表.
-
字典的 values 方法可以返回一個由字典的值組成的列表.
-
字典的 items 方法將每一個鍵值對存放到元組中, 然後將元組列表返回.
3.5 集合
set集合是一個無序不重複元素集。由於set是一個無序集合,set並不記錄元素位置,所以不支援下標操作和切片操作.
3.5.1 建立集合
# 1. 建立一個空的set集合
my_set = set()
# 2. 建立一個包含元素的集合
my_set = {10, 20, 30, 40}
print(my_set)
# 3. 用一個容器來建立集合
# 注意:set會剔除重複元素
my_set = set([1, 2, 3, 4, 5, 5])
print(my_set)
# 4. 建立一個唯一元素的字元集合
my_set = set("hello world!")
print(my_set)
3.5.2 集合新增元素
向set集合中新增元素,可以使用add()函式和update()函式,add()可以一次新增一個元素,update()函式可以一次新增多個元素.
# 建立一個空的集合
my_set = set()
# add()函式向set中新增元素
my_set.add(10)
my_set.add(20)
my_set.add(30)
# 列印set集合
print(my_set)
# update()函式新增多個元素
my_set.update([60, 40, 80, 90])
my_set.update((160, 140, 180, 190))
my_set.update("hello")
# 如果新增的元素是一個字典,那麼將字典的key新增到集合中
# my_set.update({"name": "smith", "age": 1030})
print(my_set)
3.5.3 集合刪除元素
刪除set集合中的元素可以使用pop()、remove()函式、discard()函式
-
pop()函式會刪除set集合中的任意一個元素,如果set集合為空,會丟擲KeyError錯誤。
-
remove(element)函式從集合中刪除一個元素,如果元素不存在,會丟擲KeyError錯誤。
-
discard(val)函式刪除集合中的一個元素,如果不存在,則不做任何事.
my_set = set([9, 2, 3, 4, 7])
# 刪除任意一個元素
my_set.pop()
print(my_set)
# 刪除指定元素
my_set.remove(4)
print(my_set)
# 刪除元素
my_set.discard(3)
print(my_set)
3.5.4 集合遍歷
# 建立一個空的集合
my_set = set([1, 2, 3, 4])
# 遍歷set集合
for value in my_set:
print(value, end="|")
3.5.5 集合交集和並集
my_set1 = set([1, 2, 3, 4, 5])
my_set2 = set([3, 4, 5, 6, 7])
# 1. 求兩個集合的並集
new_set1 = my_set1.union(my_set2)
# 或者
new_set2 = my_set1 | my_set2
print(new_set1)
print(new_set2)
# 2. 求兩個集合的交集
new_set3 = my_set1.intersection(my_set2)
# 或者
new_set4 = my_set1 & my_set2
print(new_set3)
print(new_set4)
3.5.6 set應用: 統計字元個數
# 統計字串中字元的個數
my_string = input("請輸入任意字串:")
# 先對字串去重
new_string = set(my_string)
# 字典記錄字元出現次數
my_count = {}
# 遍歷new_string
for ch in new_string:
my_count[ch] = my_string.count(ch)
# 輸出結果
print(my_count)
3.5.7 小結
-
集合使用一對花括號定義, 每一個元素是任意型別的物件, 不是鍵值對.
-
集合不支援切片、索引操作.
-
集合中的元素唯一且不重複.
-
集合支援 for 迴圈遍歷.
-
集合的 add 方法可以向集合中新增一個元素.
-
集合的 update 方法可以向集合中新增一個容器的元素.
-
集合的 pop 方法刪除set集合中的任意一個元素,如果set集合為空,會丟擲KeyError錯誤.
-
集合的 remove 方法從集合中刪除一個元素, 如果元素不存在, 會丟擲KeyError錯誤.
-
集合的 discard 方法刪除集合中的一個元素, 如果不存在, 則不做任何事.
-
集合的 union 方法可以返回兩個集合的並集.
-
集合的 intersection 方法可以返回兩個集合的交集
3.6 案例-員工管理系統
3.6.0 思路分析
員工管理系統可依據職責不同分為3部分:
-
資料儲存
-
業務實現
-
資料呈現
1 員工資料儲存問題
員工資訊: 編號、姓名、工資、性別
我們首要要解決的問題就是資料的儲存問題, 我們這裡要考慮的是資料以什麼樣的容器來儲存.
從業務的刪除操作、修改操作來講, 我們都需要根據鍵(員工編號)快速定位員工資訊, 達到修改和刪除的目的.
所學容器中, 字典可以根據某個不重複的關鍵字來快速定位元素. 所以我們使用字典儲存員工資訊, 字典的鍵為員工編號, 字典的值為員工資訊. 儲存結構如下:
employee = {'1001': 員工資訊, '1002': 員工資訊}
員工資訊的儲存我們使用何種型別?
因為員工資訊是多個維度的資訊, 所以本身也是個容器, 從所學容器中, 得出以下三種儲存方案:
# 1. 使用列表
employee = {'1001': ['Obama', 10000, '男'], '1002': ['Trump', 12000, '男']}
# 2. 使用元組
employee = {'1001': ('Obama', 10000, '男'), '1002': ('Trump', 12000, '男')}
# 3. 使用字典
employee = {'1001': {'name': 'Obama', 'salary': 10000, 'sex': '男'}, '1002': ['name': 'Trump', 'salary': 12000, 'sex' : '男']}
-
使用元組的話, 會導致資料無法修改, 不能達到我們的預期, 所以這個方案被否決.
-
使用列表的話, 可以實現我們的要求, 但是相較於字典的話, 操作列表中的元素就必須知道列表中名字在第幾個索引、年齡在第幾個索引、性別在第幾個索引, 並且在實現程式碼中通過索引獲取相應的姓名、年齡、性別等資料可讀性較差.
最終我字典巢狀字典的儲存結構.
employee = {'1001': {'name': 'Obama', 'salary': 10000, 'sex': '男'}, '1002': ['name': 'Trump', 'salary': 12000, 'sex' : '男']}
2 業務實現步驟
-
首先顯示操作選單.
-
獲得使用者輸入的選單編號.
-
根據選單編號選擇不同的操作執行.
-
重複上面3個步驟.
3.6.1 搭建業務框架
我們根據分析出的業務實現步驟, 先將員工管理系統的實現步驟框架搭建起來, 此時並不實現具體的功能細節.
# 儲存員工資訊
employee = {}
def show_menu():
"""顯示系統選單"""
pass
def add_new_info():
"""新增新的員工"""
pass
def remove_info():
"""刪除員工資訊"""
pass
def show_all_info():
"""列印所有員工資訊"""
pass
def edit_info():
"""修改員工資訊"""
pass
def main():
while True:
# 1. 列印選單
show_menu()
# 2. 等待使用者輸入
user_operate = input('請輸入您的操作:')
# 3. 根據使用者選擇做相應的事情
if user_operate == '1':
add_new_info()
elif user_operate == '2':
remove_info()
elif user_operate == '3':
edit_info()
elif user_operate == '4':
show_all_info()
elif user_operate == '5':
print('歡迎再次使用本系統!')
break
else:
print('您的輸入有誤, 請重新輸入!')
main()
3.6.2 選單功能實現
def show_menu():
"""顯示系統選單"""
print("*" * 30)
print("員工管理系統 v1.0")
print(" 1:新增員工資訊")
print(" 2:刪除員工資訊")
print(" 3:修改員工資訊")
print(" 4:顯示所有資訊")
print(" 5:退出員工系統")
print("*" * 30)
3.6.3 新增功能實現
-
獲得輸入的員工資訊.
-
將員工資訊依據 "鍵:值" 儲存到字典中, 每個字典表示一個員工的完整資訊.
-
以員工編號為鍵, 員工資訊為值, 將員工資訊儲存到 employee 字典中.
def add_new_info():
"""新增新的員工"""
em_number = input('請輸入員工編號:')
em_name = input('請輸入員工姓名:')
em_salary = input('請輸入員工工資:')
em_gender = input('請輸入員工性別:')
# 構建員工資訊字典
em_info = {'name': em_name, 'salary': em_salary, 'gender': em_gender}
# 以員工的編號作為鍵, 儲存員工資訊
employee[em_number] = em_info
3.6.4 刪除功能實現
我們刪除員工資訊, 根據員工的編號來刪除, 實現思路如下:
-
獲得要刪除的員工編號.
-
判斷員工編號是否存在, 如果不存在則終止函式執行.
-
如果員工資訊存在, 則根據鍵刪除員工資訊.
def remove_info():
"""刪除員工資訊"""
em_number = input('請輸入要刪除的員工編號:')
# 判斷員工編號是否存在
if em_number not in employee.keys():
print('您輸入的員工編號不存在!')
return
del employee[em_number]
print('員工編號為: %s 的員工資訊被刪除!' % em_number)
3.6.5 修改功能實現
我們根據員工編號, 修改該員工的資訊, 具體思路如下:
-
獲得要修改的員工編號.
-
判斷員工編號是否存在, 如果不存在則終止修改函式執行.
-
首先顯示員工的對應資訊, 並提示使用者輸入修改之後的值: 3.1 如果直接回車, 表示使用者無任何輸入, 則表示不修改. 3.2 如果使用者輸入值, 則將對應資訊修改為新輸入的值.
def edit_info():
"""修改員工資訊"""
em_number = input('請輸入要修改的員工編號:')
if em_number not in employee.keys():
print('您輸入的員工編號不存在!')
return
new_name = input('編號為 %s 的員工姓名為 %s, 你要修改為:' % (em_number, employee[em_number]['name']))
new_salary = input('編號為 %s 的員工工資為 %s, 你要修改為:' % (em_number, employee[em_number]['salary']))
new_gender = input('編號為 %s 的員工性別為 %s, 你要修改為:' % (em_number, employee[em_number]['gender']))
if new_name != '':
employee[em_number]['name'] = new_name
if new_salary != '':
employee[em_number]['salary'] = new_salary
if new_gender != '':
employee[em_number]['gender'] = new_gender
print('編號為 %s 的員工資訊修改成功!' % em_number)
3.6.6 顯示功能實現
直接遍歷 employee 字典, 注意字典中儲存的每一個元素都是一個鍵, 鍵為員工編號, 值為字典型別, 儲存的是員工的 資訊.
def show_all_info():
"""列印所有員工資訊"""
print('*' * 30)
for em_num, em_info in employee.items():
print('%s\t%s\t\t%s\t%s' % (em_num, em_info['name'], em_info['salary'], em_info['gender']))