2024年6月16日 Python - 資料型別

流星<。)#)))≦發表於2024-06-17

基本資料型別

Python 中的變數不需要宣告。每個變數在使用前都必須賦值,變數賦值以後該變數才會被建立。

變數沒有型別,我們所說的"型別"是變數所指的記憶體中物件的型別。

等號 = 用來給變數賦值。左邊是一個變數名,右邊是儲存在變數中的值

#!/usr/bin/python3

counter = 100  # 整型變數
miles = 1000.0  # 浮點型變數
name = "runoob"  # 字串

print(counter)	# 100
print(miles)	# 1000.0
print(name)		# runoob

標準資料型別

Python3 中有六個標準的資料型別:

  • Number(數字)
  • String(字串)
  • List(列表)
  • Tuple(元組)
  • Set(集合)
  • Dictionary(字典)

Python3 的六個標準資料型別中:

  • 不可變資料型別(3 個):Number(數字)、String(字串)、Tuple(元組)
  • 可變資料型別(3 個):List(列表)、Dictionary(字典)、Set(集合)

數字(Number)

資料型別是不允許改變的,這就意味著如果改變數字資料型別的值,將重新分配記憶體空間。

以下例項在變數賦值時 Number 物件將被建立:

var1 = 1
var2 = 10

也可以使用 del 語句刪除一些數字物件的引用

del var
del var_a, var_b

Python 支援4種不同的數值型別:

  • 整型(int) - 通常被稱為是整型或整數,是正或負整數,不帶小數點。Python3 整型是沒有限制大小的,可以當作 Long 型別使用
  • 布林(bool) 是整型的子型別
    • 在python中,能夠解釋為假的值有:
      None、0、0.0、False、所有的空容器(空列表、空元組、空字典、空集合、空字串)
  • 浮點型(float) - 浮點型由整數部分與小數部分組成,浮點型也可以使用科學計數法表示(2.5e2 = 2.5 * 10^2 = 250)
  • 複數(complex) - 複數由實數部分和虛數部分構成,可以用 a + bj ,或者 complex(a,b) 表示, 複數的實部 a 和虛部 b 都是浮點型

可以使用十六進位制和八進位制來代表整數:

print(0xA0F)    # 十六進位制      2575
print(0o37)     # 八進位制       31

數字型別轉換

有時候,我們需要對資料內建的型別進行轉換,資料型別的轉換,你只需要將資料型別作為函式名即可。

  • int(x) 將 x 轉換為一個整數
  • float(x) 將 x 轉換到一個浮點數
  • complex(x) 將 x 轉換到一個複數,實數部分為 x ,虛數部分為 0
  • complex(x, y) 將 x 和 y 轉換到一個複數,實數部分為 x,虛數部分為 y。x 和 y 是數字表示式

數字運算

在整數除法中,除法 / 總是返回一個浮點數,如果只想得到整數的結果,丟棄可能的分數部分,可以使用運算子 //

// 得到的並不一定是整數型別的數,它與分母分子的資料型別有關係

print(17 / 3)  # 5.666666666666667
print(17 // 3)  # 5
print(17 % 3)  # 2

print(7 // 2)  # 3
print(7.0 // 2)  # 3.0
print(7 // 2.0)  # 3.0
print(7.0 // 2.0)  # 3.0

不同型別的數混合運算時會將整數轉換為浮點數

print(3 * 3.75 / 1.5)  # 7.5
print(7.0 / 2)  # 3.5

在互動模式中,最後被輸出的表示式結果被賦值給變數 _ 。例如:

>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06

此處, _ 變數應被使用者視為只讀變數

數學函式

函式 返回值 ( 描述 )
abs(x) 返回數字的絕對值,如 abs(-10) 返回 10
ceil(x) 返回數字的上入整數,如 math.ceil(4.1) 返回 5
cmp(x, y) 如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。 Python 3 已廢棄,使用 (x>y)-(x<y) 替換
exp(x) 返回 e 的 x 次冪,如 math.exp(1) 返回 2.718281828459045
fabs(x) 返回數字的絕對值,如 math.fabs(-10) 返回 10.0
floor(x) 返回數字的下舍整數,如 math.floor(4.9) 返回 4
log(x) math.log(math.e) 返回 1.0 ,math.log(100,10) 返回 2.0
log10(x) 返回以 10 為基數的 x 的對數,如 math.log10(100) 返回 2.0
max(x1, x2,...) 返回給定引數的最大值,引數可以為序列
min(x1, x2,...) 返回給定引數的最小值,引數可以為序列
modf(x) 返回 x 的整數部分與小數部分,兩部分的數值符號與 x 相同,整數部分以浮點型表示
pow(x, y) x**y 運算後的值
round(x [,n]) 返回浮點數 x 的四捨五入值,如給出 n 值,則代表舍入到小數點後的位數。其實準確的說是保留值將保留到離上一位更近的一端
sqrt(x) 返回數字 x 的平方根

隨機數函式

隨機數可以用於數學,遊戲,安全等領域中,還經常被嵌入到演算法中,用以提高演算法效率,並提高程式的安全性。

常用隨機數函式:

函式 描述
choice(seq) 從序列的元素中隨機挑選一個元素,比如 random.choice(range(10)) ,從 0 到 9 中隨機挑選一個整數
randrange ([start,] stop [,step]) 從指定範圍內,按指定基數遞增的集合中獲取一個隨機數,基數預設值為 1
random() 隨機生成下一個實數,它在 [0,1) 範圍內
seed([x]) 改變隨機數生成器的種子 seed 。如果你不瞭解其原理,你不必特別去設定 seed ,Python 會幫你選擇 seed
shuffle(lst) 將序列的所有元素隨機排序
uniform(x, y) 隨機生成下一個實數,它在 [x,y] 範圍內

三角函式

Python包括以下三角函式:

函式 描述
acos(x) 返回 x 的反餘弦弧度值
asin(x) 返回 x 的反正弦弧度值。
atan(x) 返回 x 的反正切弧度值。
atan2(y, x) 返回給定的 X 及 Y 座標值的反正切值。
cos(x) 返回 x 的弧度的餘弦值。
hypot(x, y) 返回歐幾里德範數 sqrt(x*x + y*y)
sin(x) 返回的 x 弧度的正弦值。
tan(x) 返回 x 弧度的正切值。
degrees(x) 將弧度轉換為角度,如 degrees(math.pi/2) , 返回 90.0
radians(x) 將角度轉換為弧度

數學常量

常量 描述
pi 數學常量 pi(圓周率,一般以 π 來表示)
e 數學常量 e,即自然常數

字串

字串是 Python 中最常用的資料型別。我們可以使用引號( '" )來建立字串。

建立字串很簡單,只要為變數分配一個值即可。例如:

var1 = 'Hello World!'
var2 = "Runoob"

Python 訪問字串中的值

Python 不支援單字元型別,單字元在 Python 中也是作為一個字串使用。

Python 訪問子字串,可以使用方括號 [] 來擷取字串,字串的擷取的語法格式如下:

變數[頭下標:尾下標]

索引值以 0 為開始值,-1 為從末尾的開始位置。

#!/usr/bin/python3

var1 = 'Hello World!'
var2 = "Runoob"

print("var1[0]: ", var1[0])  # H
print("var2[1:5]: ", var2[1:5])  # unoo

print("已更新字串 : ", var1[:6] + 'Runoob!')  # Hello Runoob!


跳脫字元

在需要在字元中使用特殊字元時,python 用反斜槓 跳脫字元

跳脫字元 描述 例項
(在行尾時) 續行符 >>> print("line1 \ ... line2 \ ... line3") line1 line2 line3 >>>
\\ 反斜槓符號 >>> print("\\")
\' 單引號 >>> print('\'') '
\" 雙引號 >>> print("\"") "
\a 響鈴 >>> print("\a")執行後電腦有響聲。
\b 退格(Backspace) >>> print("Hello \b World!") Hello World!
\000 >>> print("\000") >>>
\n 換行 >>> print("\n") >>>
\v 縱向製表符 >>> print("Hello \v World!") Hello World! >>>
\t 橫向製表符 >>> print("Hello \t World!") Hello World! >>>
\r 回車,將 \r 後面的內容移到字串開頭,並逐一替換開頭部分的字元,直至將 \r 後面的內容完全替換完成。 >>> print("Hello\rWorld!") World! >>> print('google runoob taobao\r123456') 123456 runoob taobao
\f 換頁 >>> print("Hello \f World!") Hello World! >>>
\yyy 八進位制數,y 代表 0~7 的字元,例如:\012 代表換行。 >>> print("\110\145\154\154\157\40\127\157\162\154\144\41") Hello World!
\xyy 十六進位制數,以 \x 開頭,y 代表的字元,例如:\x0a 代表換行 >>> print("\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21") Hello World!
\other 其它的字元以普通格式輸出
#!/usr/bin/python3

print("line1 \
line2 \
line3")  # line1 line2 line3

print("\\")  # \

print('\'')  # '

print("\"")  # "

print("\a")  # 執行後電腦有響聲  

print("Hello \b World!")  # Hello World!

print("\000")  #

print("\n")

print("Hello \v World!")  # Hello  World!

print("Hello \t World!")  # Hello   World!

print("Hello\rWorld!")  # World!
print('google runoob taobao\r123456')  # 123456

print("Hello \f World!")    # Hello  World!

print("\110\145\154\154\157\40\127\157\162\154\144\41")     # Hello World!

print("\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21")   # Hello World!

print("\cdef")  # \cdef

字串運算子

下表例項變數 a 值為字串 "Hello",b 變數值為 "Python"

運算子 描述 例項
+ 字串連線 a + b 輸出結果: HelloPython
* 重複輸出字串 a*2 輸出結果:HelloHello
[] 透過索引獲取字串中字元 a[1] 輸出結果 e
[ : ] 擷取字串中的一部分,遵循左閉右開原則,str[0:2] 是不包含第 3 個字元的。 a[1:4] 輸出結果 ell
in 成員運算子 - 如果字串中包含給定的字元返回 True 'H' in a 輸出結果 True
not in 成員運算子 - 如果字串中不包含給定的字元返回 True 'M' not in a 輸出結果 True
r/R 原始字串 - 原始字串:所有的字串都是直接按照字面的意思來使用,沒有轉義特殊或不能列印的字元。 原始字串除在字串的第一個引號前加上字母 r(可以大小寫)以外,與普通字串有著幾乎完全相同的語法。 print( r'\n' ) print( R'\n' )
% 格式字串

字串格式化

Python 支援格式化字串的輸出 。儘管這樣可能會用到非常複雜的表示式,但最基本的用法是將一個值插入到一個有字串格式符 %s 的字串中。

在 Python 中,字串格式化使用與 C 中 sprintf 函式一樣的語法

#!/usr/bin/python3

print("我叫 %s 今年 %d 歲!" % ('小明', 10))    # 我叫 小明 今年 10 歲!

python字串格式化符號:

符 號 描述
%c 格式化字元及其 ASCII 碼
%s 格式化字串
%d 格式化整數
%u 格式化無符號整型
%o 格式化無符號八進位制數
%x 格式化無符號十六進位制數
%X 格式化無符號十六進位制數(大寫)
%f 格式化浮點數字,可指定小數點後的精度
%e 用科學計數法格式化浮點數
%E 作用同 %e ,用科學計數法格式化浮點數
%g %f%e 的簡寫
%G %f%E 的簡寫
%p 用十六進位制數格式化變數的地址

格式化運算子輔助指令:

符號 功能
* 定義寬度或者小數點精度
- 用做左對齊
+ 在正數前面顯示加號( + )
<sp> 在正數前面顯示空格
# 在八進位制數前面顯示零('0'),在十六進位制前面顯示'0x'或者'0X'(取決於用的是'x'還是'X')
0 顯示的數字前面填充 0 而不是預設的空格
% '%%'輸出一個單一的'%'
(var) 對映變數(字典引數)
m.n. m 是顯示的最小總寬度,n 是小數點後的位數(如果可用的話)

Python2.6 開始,新增了一種格式化字串的函式 str.format() ,它增強了字串格式化的功能

三引號

python 三引號允許一個字串跨多行,字串中可以包含換行符、製表符以及其他特殊字元

一個典型的用例是,當你需要一塊 HTML 或者 SQL 時

#!/usr/bin/python3
 
para_str = """這是一個多行字串的例項
多行字串可以使用製表符
TAB ( \t )。
也可以使用換行符 [ \n ]。
"""
print (para_str)

f-string

f-string 是 python3.6 之後版本新增的,稱之為字面量格式化字串,是新的格式化字串的語法。

之前我們習慣用百分號 %

f-string 格式化字串以 f 開頭,後面跟著字串,字串中的表示式用大括號 {} 包起來,它會將變數或表示式計算後的值替換進去,不用再去判斷使用 %s 還是 %d

#!/usr/bin/python3

name = 'Runoob'
# 之前的做法
print('Hello %s' % name)  # Hello Runoob

# 替換變數
print(f'Hello {name}')  # Hello Runoob

# 使用表示式
print(f'{1 + 2}')

w = {'name': 'Runoob', 'url': 'www.runoob.com'}
print(f'{w["name"]}: {w["url"]}')   # Runoob: www.runoob.com

在 Python 3.8 的版本中可以使用 = 符號來拼接運算表示式與結果:

x = 1
print(f'{x + 1}')  # Python 3.6     2

x = 1
print(f'{x+1=}')  # Python 3.8      x+1=2

Unicode 字串

在 Python2 中,普通字串是以 8 位 ASCII 碼進行儲存的,而 Unicode 字串則儲存為 16 位 unicode 字串,這樣能夠表示更多的字符集。使用的語法是在字串前面加上字首 u

在 Python3 中,所有的字串都是 Unicode 字串。

Python 的字串內建函式

Python 的字串常用內建函式如下:

方法 描述
capitalize() 將字串的第一個字元轉換為大寫
center(width, fillchar) 返回一個指定的寬度 width 居中的字串,fillchar 為填充的字元,預設為空格。
count(str, beg= 0,end=len(string)) 返回 str 在 string 裡面出現的次數,如果 beg 或者 end 指定則返回指定範圍內 str 出現的次數
bytes.decode(encoding="utf-8", errors="strict") Python3 中沒有 decode 方法,但我們可以使用 bytes 物件的 decode() 方法來解碼給定的 bytes 物件,這個 bytes 物件可以由 str.encode() 來編碼返回。
encode(encoding='UTF-8',errors='strict') 以 encoding 指定的編碼格式編碼字串,如果出錯預設報一個 ValueError 的異常,除非 errors 指定的是 ignore 或者 replace
endswith(suffix, beg=0, end=len(string)) 檢查字串是否以 obj 結束,如果 beg 或者 end 指定則檢查指定的範圍內是否以 obj 結束,如果是,返回 True ,否則返回 False
expandtabs(tabsize=8) 把字串 string 中的 tab 符號轉為空格,tab 符號預設的空格數是 8
find(str, beg=0, end=len(string)) 檢測 str 是否包含在字串中,如果指定範圍 beg 和 end ,則檢查是否包含在指定範圍內,如果包含返回開始的索引值,否則返回 -1
index(str, beg=0, end=len(string)) find() 方法一樣,只不過如果 str 不在字串中會報一個異常
isalnum() 如果字串至少有一個字元並且所有字元都是字母或數字則返回 True ,否則返回 False
isalpha() 如果字串至少有一個字元並且所有字元都是字母或中文字則返回 True ,否則返回 False
isdigit() 如果字串只包含數字則返回 True 否則返回 False
islower() 如果字串中包含至少一個區分大小寫的字元,並且所有這些(區分大小寫的)字元都是小寫,則返回 True,否則返回 False
isnumeric() 如果字串中只包含數字字元,則返回 True,否則返回 False
isspace() 如果字串中只包含空白,則返回 True,否則返回 False
istitle() 如果字串是標題化的(見 title() )則返回 True,否則返回 False
isupper() 如果字串中包含至少一個區分大小寫的字元,並且所有這些(區分大小寫的)字元都是大寫,則返回 True,否則返回 False
join(seq) 以指定字串作為分隔符,將 seq 中所有的元素(的字串表示)合併為一個新的字串
len(string) 返回字串長度
ljust(width[, fillchar]) 返回一個原字串左對齊,並使用 fillchar 填充至長度 width 的新字串,fillchar 預設為空格
lower() 轉換字串中所有大寫字元為小寫
lstrip() 截掉字串左邊的空格或指定字元
maketrans() 建立字元對映的轉換表,對於接受兩個引數的最簡單的呼叫方式,第一個引數是字串,表示需要轉換的字元,第二個引數也是字串表示轉換的目標
max(str) 返回字串 str 中最大的字母
min(str) 返回字串 str 中最小的字母
replace(old, new [, max]) 把 將字串中的 old 替換成 new , 如果 max 指定,則替換不超過 max 次
rfind(str, beg=0,end=len(string)) 類似於 find() 函式,不過是從右邊開始查詢
rindex( str, beg=0, end=len(string)) 類似於 index() ,不過是從右邊開始
rjust(width,[, fillchar]) 返回一個原字串右對齊,並使用 fillchar (預設空格)填充至長度 width 的新字串
rstrip() 刪除字串末尾的空格或指定字元
split(str="", num=string.count(str)) 以 str 為分隔符擷取字串,如果 num 有指定值,則僅擷取 num+1 個子字串
splitlines([keepends]) 按照行('\r', '\r\n', \n')分隔,返回一個包含各行作為元素的列表,如果引數 keepends 為 False,不包含換行符,如果為 True,則保留換行符
startswith(substr, beg=0,end=len(string)) 檢查字串是否是以指定子字串 substr 開頭,是則返回 True,否則返回 False。如果beg 和 end 指定值,則在指定範圍內檢查
strip([chars]) 在字串上執行 lstrip()rstrip()
swapcase() 將字串中大寫轉換為小寫,小寫轉換為大寫
title() 返回"標題化"的字串,就是說所有單詞都是以大寫開始,其餘字母均為小寫(見 istitle() )
translate(table, deletechars="") 根據 table 給出的表(包含 256 個字元)轉換 string 的字元, 要過濾掉的字元放到 deletechars 引數中
upper() 轉換字串中的小寫字母為大寫
zfill (width) 返回長度為 width 的字串,原字串右對齊,前面填充 0
isdecimal() 檢查字串是否只包含十進位制字元,如果是返回 true,否則返回 false

列表

序列是 Python 中最基本的資料結構。

序列中的每個值都有對應的位置值,稱之為索引,第一個索引是 0,第二個索引是 1,依此類推。

Python 有 6 個序列的內建型別,但最常見的是列表和元組。

列表都可以進行的操作包括索引,切片,加,乘,檢查成員。

此外,Python 已經內建確定序列的長度以及確定最大和最小的元素的方法。

列表是最常用的 Python 資料型別,它可以作為一個方括號內的逗號分隔值出現。

列表的資料項不需要具有相同的型別

建立一個列表,只要把逗號分隔的不同的資料項使用方括號括起來即可。如下所示:

list1 = ['Google', 'Runoob', 1997, 2000]
list2 = [1, 2, 3, 4, 5 ]
list3 = ["a", "b", "c", "d"]
list4 = ['red', 'green', 'blue', 'yellow', 'white', 'black']

訪問列表中的值

與字串的索引一樣,列表索引從 0 開始

索引也可以從尾部開始,最後一個元素的索引為 -1,往前一位為 -2

#!/usr/bin/python3

list = ['red', 'green', 'blue', 'yellow', 'white', 'black']
print(list[0])  # red
print(list[1])  # green
print(list[2])  # blue
print(list[-1])  # black
print(list[-2])  # white
print(list[-3])  # yellow


使用下標索引來訪問列表中的值,同樣你也可以使用方括號 [] 的形式擷取字元

也可以使用負數索引值擷取

#!/usr/bin/python3

nums = [10, 20, 30, 40, 50, 60, 70, 80, 90]
print(nums[0:4])  # [10, 20, 30, 40]

list = ['Google', 'Runoob', "Zhihu", "Taobao", "Wiki"]

# 讀取第二位
print("list[1]: ", list[1])     # Runoob
# 從第二位開始(包含)擷取到倒數第二位(不包含)
print("list[1:-2]: ", list[1:-2])   # ['Runoob', 'Zhihu']

更新列表

你可以對列表的資料項進行修改或更新,你也可以使用 append() 方法來新增列表項

#!/usr/bin/python3

list = ['Google', 'Runoob', 1997, 2000]

print("第三個元素為 : ", list[2])     # 1997
list[2] = 2001
print("更新後的第三個元素為 : ", list[2])     # 2001

list1 = ['Google', 'Runoob', 'Taobao']
list1.append('Baidu')
print("更新後的列表 : ", list1)   # ['Google', 'Runoob', 'Taobao', 'Baidu']

刪除列表元素

可以使用 del 語句來刪除列表的的元素

#!/usr/bin/python3

list = ['Google', 'Runoob', 1997, 2000]

print("原始列表 : ", list)  # ['Google', 'Runoob', 1997, 2000]
del list[2]
print("刪除第三個元素 : ", list)   # ['Google', 'Runoob', 2000]

列表指令碼運算子

列表對 +* 的運算子與字串相似。+ 號用於組合列表,* 號用於重複列表。

Python 表示式 結果 描述
len([1, 2, 3]) 3 長度
[1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] 組合
['Hi!'] * 4 ['Hi!', 'Hi!', 'Hi!', 'Hi!'] 重複
3 in [1, 2, 3] True 元素是否存在於列表中
for x in [1, 2, 3]: print(x, end=" ") 1 2 3 迭代

列表擷取與拼接

列表擷取與字串操作類似

L=['Google', 'Runoob', 'Taobao']

Python 表示式 結果 描述
L[2] 'Taobao' 讀取第三個元素
L[-2] 'Runoob' 從右側開始讀取倒數第二個元素: count from the right
L[1:] ['Runoob', 'Taobao'] 輸出從第二個元素開始後的所有元素

列表還支援拼接操作:

squares = [1, 4, 9, 16, 25]
squares += [36, 49, 64, 81, 100]
print(squares)  # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

巢狀列表

使用巢狀列表即在列表裡建立其它列表

a = ['a', 'b', 'c']
n = [1, 2, 3]
x = [a, n]

print(x)  # [['a', 'b', 'c'], [1, 2, 3]]
print(x[0])  # ['a', 'b', 'c']
print(x[0][1])  # b

列表函式&方法

函式 描述
len(list) 列表元素個數
max(list) 返回列表元素最大值
min(list) 返回列表元素最小值
list(seq) 將元組轉換為列表
方法 描述
list.append(obj) 在列表末尾新增新的物件
list.count(obj) 統計某個元素在列表中出現的次數
list.extend(seq) 在列表末尾一次性追加另一個序列中的多個值(用新列表擴充套件原來的列表)
list.index(obj) 從列表中找出某個值第一個匹配項的索引位置
list.insert(index, obj) 將物件插入列表
list.pop([index=-1]) 移除列表中的一個元素(預設最後一個元素),並且返回該元素的值
list.remove(obj) 移除列表中某個值的第一個匹配項
list.reverse() 反向列表中元素
list.sort( key=None, reverse=False) 對原列表進行排序
list.clear() 清空列表
list.copy() 複製列表

將列表當做堆疊使用

列表方法使得列表可以很方便的作為一個堆疊來使用,堆疊作為特定的資料結構,最先進入的元素最後一個被釋放(後進先出)。用 append() 方法可以把一個元素新增到堆疊頂。用不指定索引的 pop() 方法可以把一個元素從堆疊頂釋放出來。

stack = [3, 4, 5]
print(stack.append(6))  # None
stack.append(7)
print(stack)  # [3, 4, 5, 6, 7]

print(stack.pop())  # 7

print(stack)  # [3, 4, 5, 6]

print(stack.pop())  # 6

print(stack.pop())  # 5

print(stack)  # [3, 4]

將列表當作佇列使用

也可以把列表當做佇列用,只是在佇列裡第一加入的元素,第一個取出來;但是拿列表用作這樣的目的效率不高。在列表的最後新增或者彈出元素速度快,然而在列表裡插入或者從頭部彈出速度卻不快(因為所有其他的元素都得一個一個地移動)。

from collections import deque

queue = deque(["Eric", "John", "Michael"])
queue.append("Terry")
queue.append("Graham")
print(queue.popleft())  # Eric

print(queue.popleft())  # John

print(queue)    # deque(['Michael', 'Terry', 'Graham'])

元組

Python 的元組與列表類似,不同之處在於元組的元素不能修改。

元組使用小括號 ( ) ,列表使用方括號 [ ]

tup1 = ('Google', 'Runoob', 1997, 2000)
tup2 = (1, 2, 3, 4, 5)
tup3 = "a", "b", "c", "d"  # 不需要括號也可以
tup4 = ()  # 空元組
print(type(tup3))  # <class 'tuple'>

tup1 = (50)
print(type(tup1))  # 不加逗號,型別為整型     <class 'int'>

tup1 = (50,)
print(type(tup1))  # 加上逗號,型別為元組     <class 'tuple'>


元組與字串類似,下標索引從 0 開始,可以進行擷取,組合等。

img

訪問元組

元組可以使用下標索引來訪問元組中的值

tup1 = ('Google', 'Runoob', 1997, 2000)
tup2 = (1, 2, 3, 4, 5, 6, 7)

print("tup1[0]: ", tup1[0])     # Google
print("tup2[1:5]: ", tup2[1:5])     # (2, 3, 4, 5)

修改元組

元組中的元素值是不允許修改的,但我們可以對元組進行連線組合

tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')

# 修改元組元素操作是非法的。
# tup1[0] = 100

# 建立一個新的元組
tup3 = tup1 + tup2
print(tup3)     # (12, 34.56, 'abc', 'xyz')

刪除元組

元組中的元素值是不允許刪除的,但可以使用 del 語句來刪除整個元組

tup = ('Google', 'Runoob', 1997, 2000)

print(tup)      # ('Google', 'Runoob', 1997, 2000)
del tup
print("刪除後的元組 tup : ")
print(tup)      # NameError: name 'tup' is not defined

元組運算子

與字串一樣,元組之間可以使用 + 號和 * 號進行運算。這就意味著他們可以組合和複製,運算後會生成一個新的元組。

Python 表示式 結果 描述
len((1, 2, 3)) 3 計算元素個數
(1, 2, 3) + (4, 5, 6) (1, 2, 3, 4, 5, 6) 連線
('Hi!',) * 4 ('Hi!', 'Hi!', 'Hi!', 'Hi!') 複製
3 in (1, 2, 3) True 元素是否存在
for x in (1, 2, 3): print (x, end=" ") 1 2 3 迭代

元組索引,擷取

因為元組也是一個序列,所以我們可以訪問元組中的指定位置的元素,也可以擷取索引中的一段元素

tup = ('Google', 'Runoob', 'Taobao', 'Wiki', 'Weibo', 'Weixin')
print(tup[1])       # Runoob
print(tup[-2])      # Weibo
print(tup[1:])      # ('Runoob', 'Taobao', 'Wiki', 'Weibo', 'Weixin')
print(tup[1:4])     # ('Runoob', 'Taobao', 'Wiki')

元組內建函式

Python 元組包含了以下內建函式

方法 描述
len(tuple) 計算元組元素個數。
max(tuple) 返回元組中元素最大值。
min(tuple) 返回元組中元素最小值。
tuple(iterable) 將可迭代系列轉換為元組。
tuple1 = ('Google', 'Runoob', 'Taobao')
print(len(tuple1))  # 3

tuple2 = ('5', '4', '8')
print(max(tuple2))  # 8
print(min(tuple2))  # 4

list1 = ['Google', 'Taobao', 'Runoob', 'Baidu']
tuple3 = tuple(list1)
print(tuple3)  # ('Google', 'Taobao', 'Runoob', 'Baidu')

元組是不可變的

所謂元組的不可變指的是元組所指向的記憶體中的內容不可變。

tup = ('r', 'u', 'n', 'o', 'o', 'b')
# tup[0] = 'g'     # 不支援修改元素
# TypeError: 'tuple' object does not support item assignment

print(id(tup))  # 檢視記憶體地址

tup = (1, 2, 3)
print(id(tup))  # 記憶體地址改變

從以上例項可以看出,重新賦值的元組 tup ,繫結到新的物件了,不是修改了原來的物件。

字典

字典是另一種可變容器模型,且可儲存任意型別物件。

字典的每個鍵值 key=>value 對用冒號 : 分割,每個對之間用逗號 , 分割,整個字典包括在花括號 {} 中 ,格式如下所示:

d = {key1 : value1, key2 : value2, key3 : value3 }

注意dict 作為 Python 的關鍵字和內建函式,變數名不建議命名為 dict

鍵必須是唯一的,但值則不必。

值可以取任何資料型別,但鍵必須是不可變的,如字串,數字。

簡單的字典例項:

tinydict = {'name': 'runoob', 'likes': 123, 'url': 'www.runoob.com'}
tinydict1 = {'abc': 456}
tinydict2 = {'abc': 123, 98.6: 37}

建立空字典

使用大括號 { } 建立空字典

# 使用大括號 {} 來建立空字典
emptyDict = {}
# emptyDict = dict()    # 另一種方式

# 列印字典
print(emptyDict)    # {}

# 檢視字典的數量
print("Length:", len(emptyDict))    # 0

# 檢視型別
print(type(emptyDict))  # <class 'dict'>

訪問字典裡的值

tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}

print("tinydict['Name']: ", tinydict['Name'])   # Runoob
print("tinydict['Age']: ", tinydict['Age'])     # 7
print ("tinydict['Alice']: ", tinydict['Alice'])    # 不存在的鍵會報錯  KeyError: 'Alice'

修改字典

tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}

tinydict['Age'] = 8  # 更新 Age
tinydict['School'] = "菜鳥教程"  # 新增資訊

print("tinydict['Age']: ", tinydict['Age'])     # 8
print("tinydict['School']: ", tinydict['School'])       # 菜鳥教程

刪除字典元素

tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}

del tinydict['Name']  # 刪除鍵 'Name'
tinydict.clear()  # 清空字典
del tinydict  # 刪除字典

print("tinydict['Age']: ", tinydict['Age'])     # NameError: name 'tinydict' is not defined
print("tinydict['School']: ", tinydict['School'])

字典鍵的特性

字典值可以是任何的 python 物件,既可以是標準的物件,也可以是使用者定義的,但鍵不行。

兩個重要的點需要記住:

  1. 不允許同一個鍵出現兩次。建立時如果同一個鍵被賦值兩次,後一個值會被記住
  2. 鍵必須不可變,所以可以用數字,字串或元組充當,而用列表就不行

字典內建函式&方法

Python字典包含了以下內建函式:

函式 描述
len(dict) 計算字典元素個數,即鍵的總數。
str(dict) 輸出字典,可以列印的字串表示。
type(variable) 返回輸入的變數型別,如果變數是字典就返回字典型別。
tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}

print(len(tinydict))    # 3
print(tinydict)    # {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
print(str(tinydict))    # {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
print(type(tinydict))   # <class 'dict'>

Python 字典包含了以下內建方法:

函式 描述
dict.clear() 刪除字典內所有元素
dict.copy() 返回一個字典的淺複製
dict.fromkeys() 建立一個新字典,以序列 seq 中元素做字典的鍵,val 為字典所有鍵對應的初始值
dict.get(key, default=None) 返回指定鍵的值,如果鍵不在字典中返回 default 設定的預設值
key in dict 如果鍵在字典 dict 裡返回 true ,否則返回 false
dict.items() 以列表返回一個檢視物件
dict.keys() 返回一個檢視物件
dict.setdefault(key, default=None) get() 類似, 但如果鍵不存在於字典中,將會新增鍵並將值設為 default
dict.update(dict2) 把字典 dict2 的鍵/值對更新到 dict 裡
dict.values() 返回一個檢視物件
pop(key[,default]) 刪除字典給定鍵 key 所對應的值,返回值為被刪除的值。key 值必須給出。 否則,返回 default 值。
popitem() 隨機返回並刪除字典中的最後一對鍵和值。

集合

集合(set)是一個無序的不重複元素序列。

可以使用大括號 { } 或者 set() 函式建立集合,注意:建立一個空集合必須用 set() 而不是 { } ,因為 { } 是用來建立一個空字典。

basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
print(basket)  # 這裡演示的是去重功能     {'apple', 'orange', 'banana', 'pear'}

print('orange' in basket)  # 快速判斷元素是否在集合內       True

print('crabgrass' in basket)    # False

# 下面展示兩個集合間的運算.

a = set('abracadabra')
b = set('alacazam')
print(a)        # {'r', 'a', 'c', 'd', 'b'}
print(b)        # {'z', 'a', 'l', 'c', 'm'}

print(a - b)  # 集合a中包含而集合b中不包含的元素       {'b', 'r', 'd'}

print(a | b)  # 集合a或b中包含的所有元素       {'r', 'm', 'z', 'a', 'c', 'l', 'd', 'b'}

print(a & b)  # 集合a和b中都包含了的元素       {'a', 'c'}

print(a ^ b)  # 不同時包含於a和b的元素        {'r', 'm', 'l', 'd', 'z', 'b'}

類似列表推導式,同樣集合支援集合推導式 (Set comprehension) :

a = {x for x in 'abracadabra' if x not in 'abc'}
print(a)    # {'r', 'd'}

集合的基本操作

新增元素

thisset = set(("Google", "Runoob", "Taobao"))
thisset.add("Facebook")  # 新增元素,如果元素已存在,則不進行任何操作
print(thisset)  # {'Facebook', 'Runoob', 'Taobao', 'Google'}

thisset.update({1, 3})  # 可以新增元素,且引數可以是列表,元組,字典等
print(thisset)  # {'Facebook', 1, 3, 'Taobao', 'Google', 'Runoob'}

thisset.update([1, 4], [5, 6])
print(thisset)      # {1, 3, 4, 5, 6, 'Facebook', 'Runoob', 'Taobao', 'Google'}

移除元素

thisset = set(("Google", "Runoob", "Taobao"))
thisset.remove("Taobao")
print(thisset)

# thisset.remove("Facebook")  # 不存在會發生錯誤      KeyError: 'Facebook'

thisset.discard("Facebook")     # 移除集合中的元素,且如果元素不存在,不會發生錯誤

x = thisset.pop()       # 隨機刪除集合中的一個元素
print(x)

set 集合的 pop 方法會對集合進行無序的排列,然後將這個無序排列集合的左面第一個元素進行刪除。

計算集合元素個數

thisset = set(("Google", "Runoob", "Taobao"))
print(len(thisset))     # 3

清空集合

s.clear()

判斷元素是否在集合中存在

x in s

判斷元素 x 是否在集合 s 中,存在返回 True ,不存在返回 False

集合內建方法完整列表

方法 描述
add() 為集合新增元素
clear() 移除集合中的所有元素
copy() 複製一個集合
difference() 返回多個集合的差集
difference_update() 移除集合中的元素,該元素在指定的集合也存在。
discard() 刪除集合中指定的元素
intersection() 返回集合的交集
intersection_update() 返回集合的交集。
isdisjoint() 判斷兩個集合是否包含相同的元素,如果沒有返回 True,否則返回 False。
issubset() 判斷指定集合是否為該方法引數集合的子集。
issuperset() 判斷該方法的引數集合是否為指定集合的子集
pop() 隨機移除元素
remove() 移除指定元素
symmetric_difference() 返回兩個集合中不重複的元素集合。
symmetric_difference_update() 移除當前集合中在另外一個指定集合相同的元素,並將另外一個指定集合中不同的元素插入到當前集合中。
union() 返回兩個集合的並集
update() 給集合新增元素

資料型別轉換

資料型別的轉換,一般情況下你只需要將資料型別作為函式名即可。

Python 資料型別轉換可以分為兩種:

  • 隱式型別轉換 - 自動完成
  • 顯式型別轉換 - 需要使用型別函式來轉換

隱式型別轉換

在隱式型別轉換中,Python 會自動將一種資料型別轉換為另一種資料型別,不需要我們去幹預。

以下例項中,我們對兩種不同型別的資料進行運算,較低資料型別(整數)就會轉換為較高資料型別(浮點數)以避免資料丟失。

num_int = 123
num_flo = 1.23

num_new = num_int + num_flo

print("datatype of num_int:", type(num_int))    # <class 'int'>
print("datatype of num_flo:", type(num_flo))    # <class 'float'>

print("Value of num_new:", num_new)     # 124.23
print("datatype of num_new:", type(num_new))    # <class 'float'>

例項:整型資料與字串型別的資料進行相加:

num_int = 123
num_str = "456"

print("Data type of num_int:", type(num_int))
print("Data type of num_str:", type(num_str))

print(num_int + num_str)    # 異常:TypeError: unsupported operand type(s) for +: 'int' and 'str'

整型和字串型別運算結果會報錯,輸出 TypeError。 Python 在這種情況下無法使用隱式轉換。

但是,Python 為這些型別的情況提供了一種解決方案,稱為顯式轉換。

顯式型別轉換

在顯式型別轉換中,使用者將物件的資料型別轉換為所需的資料型別。 我們使用 int()、float()、str() 等預定義函式來執行顯式型別轉換。

int() 強制轉換為整型:

x = int(1)  # x 輸出結果為 1
y = int(2.8) # y 輸出結果為 2
z = int("3") # z 輸出結果為 3

float() 強制轉換為浮點型:

x = float(1)   # x 輸出結果為 1.0
y = float(2.8)  # y 輸出結果為 2.8
z = float("3")  # z 輸出結果為 3.0
w = float("4.2") # w 輸出結果為 4.2

str() 強制轉換為字串型別:

x = str("s1") # x 輸出結果為 's1'
y = str(2)   # y 輸出結果為 '2'
z = str(3.0) # z 輸出結果為 '3.0'

整型和字串型別進行運算,就可以用強制型別轉換來完成:

num_int = 123
num_str = "456"

print("num_int 資料型別為:", type(num_int))  # <class 'int'>
print("型別轉換前,num_str 資料型別為:", type(num_str))  # <class 'str'>

num_str = int(num_str)  # 強制轉換為整型
print("型別轉換後,num_str 資料型別為:", type(num_str))  # <class 'int'>

num_sum = num_int + num_str

print("num_int 與 num_str 相加結果為:", num_sum)  # 579
print("sum 資料型別為:", type(num_sum))  # <class 'int'>


以下幾個內建的函式可以執行資料型別之間的轉換。這些函式返回一個新的物件,表示轉換的值。

函式 描述
int(x [,base]) 將 x 轉換為一個整數
float(x) 將 x 轉換到一個浮點數
complex(real [,imag]) 建立一個複數
str(x) 將物件 x 轉換為字串
repr(x) 將物件 x 轉換為表示式字串
eval(str) 用來計算在字串中的有效 Python 表示式,並返回一個物件
tuple(s) 將序列 s 轉換為一個元組
list(s) 將序列 s 轉換為一個列表
set(s) 轉換為可變集合
dict(d) 建立一個字典。d 必須是一個 (key, value)元組序列。
frozenset(s) 轉換為不可變集合
chr(x) 將一個整數轉換為一個字元
ord(x) 將一個字元轉換為它的整數值
hex(x) 將一個整數轉換為一個十六進位制字串
oct(x) 將一個整數轉換為一個八進位制字串

遍歷技巧

在字典中遍歷時,關鍵字和對應的值可以使用 items() 方法同時解讀出來:

knights = {'gallahad': 'the pure', 'robin': 'the brave'}
for k, v in knights.items():
    print(k, v)

"""
gallahad the pure
robin the brave
"""

在序列中遍歷時,索引位置和對應值可以使用 enumerate() 函式同時得到:

for i, v in enumerate(['tic', 'tac', 'toe']):
    print(i, v)

"""
0 tic
1 tac
2 toe
"""

同時遍歷兩個或更多的序列,可以使用 zip() 組合:

questions = ['name', 'quest', 'favorite color']
answers = ['lancelot', 'the holy grail', 'blue']
for q, a in zip(questions, answers):
    print('{0} :: {1}'.format(q, a))

"""
name :: lancelot
quest :: the holy grail
favorite color :: blue
"""

要反向遍歷一個序列,首先指定這個序列,然後呼叫 reversed() 函式:

for i in reversed(range(1, 10, 2)):
    print(i, end=", ")

# 9, 7, 5, 3, 1, 

要按順序遍歷一個序列,使用 sorted() 函式返回一個已排序的序列,並不修改原值:

basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
for f in sorted(set(basket)):
    print(f)

"""
apple
banana
orange
pear
"""

推導式

Python 推導式是一種獨特的資料處理方式,可以從一個資料序列構建另一個新的資料序列的結構體。

Python 支援各種資料結構的推導式:

  • 列表(list)推導式
  • 字典(dict)推導式
  • 集合(set)推導式
  • 元組(tuple)推導式

列表推導式

列表推導式格式為:

[表示式 for 變數 in 列表] 
[表示式 for 變數 in 列表 if 條件]

列表推導式提供了從序列建立列表的簡單途徑。通常應用程式將一些操作應用於某個序列的每個元素,用其獲得的結果作為生成新列表的元素,或者根據確定的判定條件建立子序列。

每個列表推導式都在 for 之後跟一個表示式,然後有零到多個 for 或 if 子句。返回結果是一個根據表達從其後的 for 和 if 上下文環境中生成出來的列表。如果希望表示式推匯出一個元組,就必須使用括號。

這裡我們將列表中每個數值乘三,獲得一個新的列表:

vec = [2, 4, 6]
l = [3 * x for x in vec]
print(l)  # [6, 12, 18]

print([[x, x ** 2] for x in vec])   # [[2, 4], [4, 16], [6, 36]]


對序列裡每一個元素逐個呼叫某方法:

freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
print([weapon.strip() for weapon in freshfruit])    # ['banana', 'loganberry', 'passion fruit']

用 if 子句作為過濾器:

vec = [2, 4, 6]

print([3 * x for x in vec if x > 3])  # [12, 18]

print([3 * x for x in vec if x < 2])  # []

一些關於迴圈和其它技巧的演示:

vec1 = [2, 4, 6]
vec2 = [4, 3, -9]
print([x * y for x in vec1 for y in vec2])  # [8, 6, -18, 16, 12, -36, 24, 18, -54]

print([x + y for x in vec1 for y in vec2])  # [6, 5, -7, 8, 7, -5, 10, 9, -3]

print([vec1[i] * vec2[i] for i in range(len(vec1))])    # [8, 12, -54]

列表推導式可以使用複雜表示式或巢狀函式:

print([str(round(355 / 113, i)) for i in range(1, 6)])  # ['3.1', '3.14', '3.142', '3.1416', '3.14159']

字典推導式

字典推導基本格式:

{ key_expr: value_expr for value in collection }
# 或
{ key_expr: value_expr for value in collection if condition }

使用字串及其長度建立字典:

listdemo = ['Google', 'Runoob', 'Taobao']
# 將列表中各字串值為鍵,各字串的長度為值,組成鍵值對
newdict = {key: len(key) for key in listdemo}
print(newdict)      # {'Google': 6, 'Runoob': 6, 'Taobao': 6}

提供三個數字,以三個數字為鍵,三個數字的平方為值來建立字典:

dic = {x: x**2 for x in (2, 4, 6)}
print(dic)  # {2: 4, 4: 16, 6: 36}

print(type(dic))    # <class 'dict'>

集合推導式

集合推導式基本格式:

{ expression for item in Sequence }
# 或
{ expression for item in Sequence if conditional }

計算數字 1,2,3 的平方數:

setnew = {i ** 2 for i in (1, 2, 3)}
print(setnew)   # {1, 4, 9}

判斷不是 abc 的字母並輸出:

a = {x for x in 'abracadabra' if x not in 'abc'}
print(a)    # {'r', 'd'}
print(type(a))  # <class 'set'>

元組推導式

元組推導式可以利用 range 區間、元組、列表、字典和集合等資料型別,快速生成一個滿足指定需求的元組。

元組推導式基本格式:

(expression for item in Sequence )
# 或
(expression for item in Sequence if conditional )

元組推導式和列表推導式的用法也完全相同,只是元組推導式是用 () 圓括號將各部分括起來,而列表推導式用的是中括號 [] ,另外元組推導式返回的結果是一個生成器物件。

例如,我們可以使用下面的程式碼生成一個包含數字 1\~9 的元組:

a = (x for x in range(1, 10))
print(a)  # 返回的是生成器物件
# <generator object <genexpr> at 0x0000015F0DB15FC0>

print(tuple(a))  # 使用 tuple() 函式,可以直接將生成器物件轉換成元組
# (1, 2, 3, 4, 5, 6, 7, 8, 9)

迭代器

迭代是 Python 最強大的功能之一,是訪問集合元素的一種方式。

迭代器是一個可以記住遍歷的位置的物件。

迭代器物件從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。

迭代器有兩個基本的方法:iter()next()

字串,列表或元組物件都可用於建立迭代器:

list = [1, 2, 3, 4]
it = iter(list)  # 建立迭代器物件
print(next(it))  # 輸出迭代器的下一個元素  1

print(next(it))  # 2

迭代器物件可以使用常規 for 語句進行遍歷:

#!/usr/bin/python3

list = [1, 2, 3, 4]
it = iter(list)  # 建立迭代器物件
for x in it:
    print(x, end=", ")

也可以使用 next() 函式:

#!/usr/bin/python3

import sys  # 引入 sys 模組

list = [1, 2, 3, 4]
it = iter(list)  # 建立迭代器物件

while True:
    try:
        print(next(it))
    except StopIteration:
        sys.exit()

建立一個迭代器

把一個類作為一個迭代器使用需要在類中實現兩個方法 __iter__()__next__()

類都有一個建構函式,Python 的建構函式為 __init__() ,它會在物件初始化的時候執行。

__iter__() 方法返回一個特殊的迭代器物件, 這個迭代器物件實現了 __next__() 方法並透過 StopIteration 異常標識迭代的完成。

__next__() 方法(Python 2 裡是 next() )會返回下一個迭代器物件。

建立一個返回數字的迭代器,初始值為 1,逐步遞增 1:

class MyNumbers:
    def __iter__(self):
        self.a = 1
        return self

    def __next__(self):
        x = self.a
        self.a += 1
        return x


myclass = MyNumbers()
myiter = iter(myclass)

print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))

輸出結果為:

1
2
3
4
5

StopIteration

StopIteration 異常用於標識迭代的完成,防止出現無限迴圈的情況,在 __next__() 方法中我們可以設定在完成指定迴圈次數後觸發 StopIteration 異常來結束迭代。

在 20 次迭代後停止執行:

class MyNumbers:
    def __iter__(self):
        self.a = 1
        return self

    def __next__(self):
        if self.a <= 20:
            x = self.a
            self.a += 1
            return x
        else:
            raise StopIteration


myclass = MyNumbers()
myiter = iter(myclass)

for x in myiter:
    print(x)

生成器

在 Python 中,使用了 yield 的函式被稱為生成器(generator)。

跟普通函式不同的是,生成器是一個返回迭代器的函式,只能用於迭代操作,更簡單點理解生成器就是一個迭代器。

在呼叫生成器執行的過程中,每次遇到 yield 時函式會暫停並儲存當前所有的執行資訊,返回 yield 的值,並在下一次執行 next() 方法時從當前位置繼續執行。

呼叫一個生成器函式,返回的是一個迭代器物件。

#!/usr/bin/python3

import sys


def fibonacci(n):  # 生成器函式 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n):
            return
        yield a
        a, b = b, a + b
        counter += 1


f = fibonacci(10)  # f 是一個迭代器,由生成器返回生成

while True:
    try:
        print(next(f), end=" ")
    except StopIteration:
        sys.exit()

相關文章