1 數據分類
python中有7種標准數據類型,分別是布爾型、數字型、字符串、元組、列表、字典和集合,根據數據的特點,可以從兩個角度去理解和區分幾種數據類型:可變與不可變、有序與無序。
1.1 可變與不可變
可變與不可變的意思,即是該數據是只讀的還是可以修改的,在python中布爾型、數字型、字符串和元組是不可變數據類型,它們的值是只讀的不能修改;列表、字典和集合是可變數據類型,它們的值可以修改。
1.2 有序與無序
有序是說某數據類型中的每個元素都有一個位置信息index,從而可以借助數據類型名與位置信息index訪問數據中的元素值,即可以做索引和切片。在Python里字符串、元組、列表是有序的;字典與集合是無序的。
最后,對可變與不可變、有序與無序做一個總結,幾者關系如下圖:
而不同數據類型,內部的組成元素,經常可以是其他的數據類型,即可以互相嵌套,見下圖。
2 不可變數據類型
2.1 布爾型(bool)
布爾型數據也叫布爾值,只有兩種取值:True
和False
。布爾值有兩種生成方式:
- 布爾操作符:and 、or 、not。運行優先次序是not > and > or
- 比較操作符: 詳見下表
操作符 | 含義 |
---|---|
== | 等於 |
!= | 不等於 |
< | 小於 |
> | 大於 |
<= | 小於等於 |
>= | 大於等於 |
not 5
not 5 and 5 < 1 or 5 > 1
(not 5) and (5 < 1 or 5 > 1) # 加括號()可以控制運算先后次序
2.2 數字型(number)
數字型數據分為三類,其中int
和float
最常用:
- 整數型(int)
- 浮點數(float):科學計數法,也是浮點數類型
- 復數類型(complex):z = a + bj
三者存在拓展關系:整數 → 浮點數 → 復數,即「不同類型混合運算結果是最寬類型」。
2.2.1 運算操作符
數字型數據之間,可以通過運算操作符進行換算,常用運算符見下表:
運算操作符 | 含義 |
---|---|
x + y | x與y之和 |
x - y | x與y之差 |
x * y | x與y之積 |
x / y | x與y之商 |
x // y | x與y之整數商,即不大於x與y之商的最大整數 |
x % y | x與y之商的余數,也叫模運算 |
x ** y | x的y次冪,即x^y |
- x | x的負值 |
+ x | x本身 |
# 整數商
9//4
# 模運算,可以把任意運算,映射到0-3之間
9 % 4
# x的y次冪,有兩種表達方式
pow(2, 3)
2**3
2.2.2 內置函數
python中的內置函數底層由C語言編寫,運行速度快,推薦優先使用。
內置函數 | 含義 |
---|---|
abs(x) | x的絕對值 |
divmod(x, y) | (x//y, x%y), 輸出為二元組形式 |
pow(x, y) | 與x**y相同 |
round(x, [ndigits]) | 向整數位最靠近的偶數進行四舍五入,保留ndigits位小數 |
max(x1, x2, ...) | 求最大值 |
min(x1, x2, ...) | 求最小值 |
divmod(10, 3) # 輸出為二元組形式
# 向最靠近的偶數進行四舍五入,目的是想要減少誤差(銀行家算法)
round(4.5)
round(5.5)
# 若對一堆數進行四舍五入,可以都加一個非常小的數,再用round()
round(4.500000000000001)
2.3 字符串(string)
字符串是用單引號('')、雙引號(" ")、或多引號(''' ''')括起來的一個或多個字符串,引號之間可以相互嵌套,用來表示復雜字符串。
2.3.1 轉義字符
轉義字符\,表示轉義,常用在一些字符或符號前面,共同組成新的含義,常用的有:
\
:后接符號,表示原來是什么作用,轉義之后還是什么作用,如 " 前面加 \ 就能打印出 "\n
:表示換行\t
:表示Tab
鍵
拓展用法:在字符串的引號前加上r,就成為原始字符串,忽略所有轉義字符
a = 'abc\ncde' # \n表示換行
print(a)
a = 'abc\tabc' # \t表示Tab鍵
print(a)
aa = 'Tom said, \'Let\'s go\'?' # 轉義字符的運用
print(aa)
# 打印出轉義字符
bb = '\\'
print(bb)
# 打印指定格式:三重引號
print('''Dear Tom,
I\'m happy to accept your letter. \
Now I\'ll tell you about my plan to my summer vacation.
......
Yours,
Xiao Qiang''')
2.3.2 索引與切片
首先,讓我們先學習索引和切片的定義:
- 索引:在有序序列中,通過元素的位置編號(index)來訪問單個元素並生成一個新子集的叫索引
- 切片:在有序序列中,通過元素的位置編號(index)來訪問多個元素並生成一個新子集的叫切片
兩者的區別在於索引訪問的是單個元素,切片訪問的是某范圍內的多個元素,兩者的使用語法如下:
# 索引
子集名 = 有序序列名[index]
# 切片
子集名 = 有序序列名[start : end : step]
其中,有序序列指字符串、元組、列表三種數據類型;切片語法中的三個參數分別指起點、終點、步長。需要特別注意的是,索引與切片在實際使用中存在負索引與負方向。如下圖所示,有序序列的index分為正向與反向,則要訪問元素 “h” 則有兩種等價的實現方式:str[0]、str[-9],這就是負索引。同理,在切片中用步長的符號來表示方向,正號表示正向切片(從起點往右切片),負號表示反向切片(從起點往左切片)。另外,索引和切片都是「新生成」,原始數據不發生改變。

a = 'hello tom'
# 索引
a[0] # 正索引
a[-9] # 負索引
# 切片
a[0:5:1] # 正切片
a[0:5:-1] # 負切片
a[-1:5:-1] # 負切片
2.3.3 內置函數
函數 | 含義 |
---|---|
len(x) | 返回字符串長度 |
str(x) | 把任意類型x字符串化 |
ord(x) | 返回單字符表示的unicode編碼 |
chr(x) | 返回unicode編碼對應的單字符 |
hex(x) | 返回整數x對應十六進制的小寫形式字符串 |
oct(x) | 返回整數x對應八進制的小寫形式字符串 |
eval(x) | 把任意字符串轉化為表達式並求值 |
a = 'asgasdga sgasg' # 空格也算長度
len(a)
a = 'c'
ord(a) # 單字符對應的unicode編碼
chr(99) # unicode編碼對應的單字符
eval('4+5')
2.3.4 常用方法
2.3.4.1 查找
方法 | 含義 |
---|---|
find() | 查找字符串在另一字符串指定范圍內首次出現位置,不存在返回-1 |
rfind() | 最后一次出現位置,不存在返回-1 |
index() | 查找字符串在另一字符串指定范圍內首次出現位置,不存在拋出異常 |
rindex() | 最后一次出現位置,不存在拋出異常 |
count() | 返回一個字符串在另一個字符串中出現次數 |
s = 'ashuigasgi'
s.find('a')
s.rfind('8')
s.index('h')
s.find('9')
s.count('0')
2.3.4.2 分割與拼接
方法 | 含義 | 是否新生成 |
---|---|---|
split() | 指定字符為分隔符,從字符串左端開始分割成多個字符,返回列表 | 是 |
rsplit() | 從右端開始分割 | 是 |
partition() | 字符串分割成3部分:分割符前的字符串、分隔符字符串、分隔符后的字符串 | 是 |
rpartition() | 從右端開始分割 | 是 |
join() | 將字符串列表拼接成字符串,並在相鄰字符串直接插入指定字符 | 是 |
+ | 拼接字符串 | 是 |
* | 復制字符串 | 是 |
s = 'apple, peach, banana, peach, pear'
s.split(',') # 用什么分割
s.split(',', 2) # 分割幾次
s.partition('peach')
x = ['apple', 'peach', 'banana', 'peach', 'pear']
'/'.join(x)
' '.join(x) # 用空格拼接
a = '123'
b = 'abc'
a+b
a*3
2.3.4.3 大小寫
方法 | 含義 | 是否新生成 |
---|---|---|
lower() | 返回字符串的副本,全部字符串小寫 | 是 |
upper() | 返回字符串的大寫副本 | 是 |
capitalize() | 將字符串首字母大寫 | 是 |
title() | 將每個單詞的首字母大寫 | 是 |
swapcase() | 大小寫互換 | 是 |
s = 'Apple,Peach,Banana,Peach,Pear'
s.lower() # 全部小寫
s.upper() # 全部大寫
s = 'apple,peach,banana,peach,pear'
s.capitalize() # 字符串首字母大寫
s.upper() # 每個單詞首字母大寫
s.swapcase() # 大小寫互換
2.3.4.4 判斷
判斷的返回值都是True 或 False。
方法 | 含義(判斷字符串) |
---|---|
isdigit() | 是否只由數字組成 |
isalpha() | 是否只由字母組成 |
isalnum() | 是否只由數字或字母組成 |
isupper() | 所有字母是否為大寫 |
islower() | 所有字母是否為小寫 |
isspace() | 是否只由空白字符組成 |
istitle() | 是否單詞首字母都是大寫,且后面都是小寫 |
isdecimal() | 是否只包含十進制字符 |
isnumeric() | 是否所有字符都是數字 |
isprintable() | 是否所有字符都可以打印 |
in | 在…內 |
not in | 不在…內 |
a = 'hello world'
'hu' not in a
x = ' '
x.isspace()
s = 'Apple PeacH'
s.istitle()
2.3.4.5 移除空白字符串
方法 | 含義 | 是否新生成 |
---|---|---|
strip() | 移除左右兩側指定的字符,不指定默認移除空格 | 是 |
lstrip() | 移除左側指定的字符,不指定默認移除空格 | 是 |
rstrip() | 移除右側指定的字符,不指定默認移除空格 | 是 |
s = ' abcd '
s.strip() # 不指定,默認移除空格
s = '****abcd******'
s.strip('*') # 指定
s = ' abcd '
s.lstrip() # 移除左邊
s.rstrip() # 移除右邊
2.3.4.6 對齊文本
方法 | 含義 | 是否新生成 |
---|---|---|
ljust() | 返回左對齊的字符串,並使用指定長度的填充符號,不指定默認使用空格 | 是 |
rjust() | 返回右對齊的字符串,並使用指定長度的填充符號,不指定默認使用空格 | 是 |
center() | 返回居中對齊的字符串,並使用指定長度的填充符號,不指定默認使用空格 | 是 |
s = 'abjd'
s.ljust(10)
s.center(10, '*')
2.3.4.7 映射
兩者一般配對使用。
方法 | 含義 |
---|---|
maketrans() | 生成字符串映射表 |
translate() | 按映射表關系轉換字符串 |
s1 = 'abcde' # 原字符串中要替換的字符
num = '12345' # 相應的映射字符的字符串。
s2 = 'aaxxbbxxccxxddxxee' # 原字符串
hah = s1.maketrans(s1, num)
hah
s2.translate(hah)
2.3.4.8 其他方法
方法 | 含義(判斷字符串) | 是否新生成 |
---|---|---|
replace() | 用指定字符串替代原字符串,並返回替換后的新字符串 | 是 |
startswith() | 判斷字符串:是否以指定字符串開頭,並可以指定范圍,返回布爾值 | / |
endswith() | 判斷字符串:是否以指定字符串結尾,並可以指定范圍,返回布爾值 | / |
zfill() | 在字符串左側用0填充至指定長度,並返回補齊后的字符串 | 是 |
encode() | 以指定編碼格式對字符串進行編碼,返回編碼后的二進制 | / |
decode() | 對編碼后的字符串進行解碼 | / |
s = 'aaxxbbxxccxxddxxee' # 原字符串
s.replace('xx', 'oo')
s.replace('ff', 'oo') # 如果不存在,返回原字符串
s = 'apple,peach,banana,peach,pear'
s.startswith('a') # 是不是以a開頭
s.startswith('apple') # 是不是以apple開頭
s.startswith('peach', 6) # 判斷單詞是不是從第i個開始
s = 'apple'
s.zfill(10)
s = '中國'
s1 = s.encode('utf-8') # utf8編碼
s1
s1.decode() # 編碼
2.3.5 字符串格式化
2.3.5.1 format格式化
為了將其他類型數據類型轉換為字符串,需要進行格式化,通過format()
方法實現,有三種常見形式:
格式化方法 | 語法形式 |
---|---|
按從左到右傳值 | "字符串 - {} -字符串- {}".format("內容1", "內容2") |
按指定位置傳值 | "字符串 - {2} -字符串- {1}".format("內容1", "內容2") |
按設置參數傳值 | "字符串 - {變量名1} -字符串- {變量名2}".format(變量名1="內容1", 變量名2="內容2") |
# 按默認順序對字符串進行格式化
s = "I'm dark {}, I'm {} years old!"
s1 = s.format('knight', '28')
print(s1)
# 按位置對字符串進行格式化
s = "I'm dark {1}, I'm {0} years old!"
s1 = s.format('28', 'knight')
print(s1)
# 按參數設置對字符串進行格式化
s = "I'm dark {name}, I'm {age} years old!"
s1 = s.format(age='28', name='knight')
print(s1)
2.3.5.2 format格式控制
format除了可以進行字符串格式化以外,還可以對字符串進行「格式控制」,使得字符串呈現不同的表現形式,語法:{<參數序號>: <格式控制標記>}。
其中,<格式控制標記>用來控制參數顯示的格式,包括:<填充><對齊><寬度>,<.精度><類型>6 個字段,這些字段都是可選的,能組合使用。
更多用法,可參見鏈接:https://blog.csdn.net/i_chaoren/article/details/77922939
s = 'dark knight'
'{0:20}'.format(s) # 默認左對齊
'{0:>30}'.format(s) # >表示右對齊
'{0:^30}'.format(s) # ^表示居中對齊
'{0:*^30}'.format(s) # 指定填充符號
'{0:*^30,}'.format(123456789) # 用逗號顯示數字類型的千位分隔符
'{0:.2f}'.format(123.456789) # 指定浮點數精度
'{0:.2f}, {1:.4f}'.format(1/3, 5/7) # 不同位置取不同精度
2.4 元組(tuple)
元組,外層用括號()
包裹,里面元素用逗號分割的數據類型,如(1, 2)
,它是一種有序序列。注意,元組外層的()
也可以不寫,如1, 2
也是元組,等價於(1, 2)
。需要注意的是,元組只有一個元素的時候,元素后一定要加逗號,否則數據類型不確定。
t3 = (1) # int型
t4 = (1,) # 元組
t5 = ('kane') # str型
t6 = ('kane',) # 元組
print(t3, type(t3))
print(t4, type(t4))
print(t5, type(t5))
print(t6, type(t6))
元組本身是不可修改的數據類型,但元組中若包含可變序列(如列表),則可變序列中的元素可修改,這屬於原地操作,不改變元組內存id。
t1 = ([1, 2, 3], 7, 8, 9)
print(t1, type(t1))
t1[0].append(4)
print(t1)
元組可以存儲程序里只讀的有序序列數據,但在Python里,元組通常是用於python訪問數據庫時從數據庫提取回結果集時的數據類型。
2.4.1 融化與凍結
融化與凍結,實質就是元組和列表的相互轉化。
- 融化:融化元組,用
list()
- 凍結:凍結列表,用
tuple
a = (1, 2, 3, 4)
list(a) # 融化,元組變列表
b = [5, 6, 7, 8]
tuple(b) # 凍結,列表變元組
2.4.2 索引和切片
同字符串、列表的索引切片,邏輯一樣。
t = (1, 'aa', {'abc': 123, 'cde': 789, 'efg': [11, 22, 33]})
t[2]['efg'][1]
2.4.3 序列解包
一次給多個變量賦值的方法叫序列解包,常用的序列解包方法有:
- 字符串序列解包
- 元組序列解包
- 列表序列解包
- 內置對象序列解包
a, b = [1, 2] # 列表的序列解包
a
b
# a, b = 4, 5 # 這也是元組的序列解包
t1, t2 = (4, 5) # 元組的序列解包
t1
t2
c, d = 'sd' # 字符串的序列解包
c
d
e, f = range(2) # 內置對象的序列解包
e
f
x, y = map(str, range(2)) # 內置對象的序列解包
x
y
2.4.4 生成器表達式
和列表推導式類似,只是保存的是算法,且最外層用的是(),用法詳見列表推導式。
方法 | 含義 | 形式 |
---|---|---|
列表推導式 | 保存元素,直接輸出 | [ ] |
字典推導式 | 保存元素,直接輸出 | { } |
生成器表達式 | 保存算法,元素用 .__next__() 或for循環訪問 | ( ) |
[i for i in range(10) if i % 2 == 0] # 列表推導式——保存的是元素
(i for i in range(10) if i % 2 == 0) # 生成器表達式——保存的是算法
# 一般是逐個訪問生成器表達式的元素,在計算的時候,用for循環逐個讀出來
g = (i for i in range(10) if i % 2 == 0)
g.__next__()
g.__next__()
g.__next__()
# 用for循環逐個訪問生成器表達式中的元素
g = (i for i in range(10) if i % 2 == 0)
for i in g:
print(i)
# 生成器表達式中的元素訪問一次后就會失效,要想多次重復訪問,就得重新生成生成器表達式
h = (i**2 for i in range(10))
4 in h # 第一次訪問
4 in h # 第二次訪問