【萬(wàn)字長(zhǎng)文】回顧|Python中的數(shù)據(jù)結(jié)構(gòu)
列表
列表的特點(diǎn):
列表的創(chuàng)建方式
基本的列表操作
列表方法
列表生成式
元組
字符串
格式化字符串
寬度、精度和千位分隔符
對(duì)其和填充
字符串編碼
字符串方法
字典
創(chuàng)建字典
基本的字典操作
將字符串格式設(shè)置功能用于字典
字典方法
字典生成式
集合
創(chuàng)建集合
集合方法
集合生成式
列表
變量可以存儲(chǔ)一個(gè)元素,而列表是一個(gè)“大容器"可以存儲(chǔ)N多個(gè)元素,程序可以方便地對(duì)這些數(shù)據(jù)進(jìn)行整體操作 列表相當(dāng)于其它語(yǔ)言中的數(shù)組 列表示意圖 
列表的特點(diǎn):
列表元素按照順序有序排列 索引映射唯一一個(gè)數(shù)據(jù) 列表可以重復(fù)存儲(chǔ)數(shù)據(jù) 任意數(shù)據(jù)類型混存 根據(jù)需要?jiǎng)討B(tài)分配和回收內(nèi)存
列表的創(chuàng)建方式
使用中括號(hào) 使用內(nèi)置函數(shù)list()
l_1 = ["hello","world"]
l_2 = list(("hello","world") )
l_1
l_2
['hello', 'world']
['hello', 'world']
基本的列表操作
可對(duì)列表執(zhí)行所有的標(biāo)準(zhǔn)序列操作,如索引、切片、拼接和相乘,但列表的有趣之處在于它不同于元組 是可以修改的。
修改列表:給元素賦值
修改列表很容易,只需使用索引表示法給特定位置的元素賦值即可。
x = [1, 1, 1]
x[1] = 2
x
[1, 2, 1]
刪除元素
從列表中刪除元素也很容易,只需使用del語(yǔ)句即可。
names = ['Alice', 'Beth', 'Cecil', 'Dee-Dee', 'Earl']
del names[2]
names
['Alice', 'Beth', 'Dee-Dee', 'Earl']
切片
name = list('Perl')
name
name[2:] = list('ar')
name
['P', 'e', 'r', 'l']
['P', 'e', 'a', 'r']
使用切片賦值,可將切片替換為長(zhǎng)度與其不同的序列
name = list('Perl')
name[1:] = list('ython')
name
['P', 'y', 't', 'h', 'o', 'n']
使用切片賦值還可在不替換原有元素的情況下插入新元素。
numbers = [1, 5]
numbers[1:1] = [2, 3, 4]
numbers
[1, 2, 3, 4, 5]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 如果切片結(jié)束于序列末尾,可省略第二個(gè)索引
numbers[-3:]
# 如果切片始于序列開(kāi)頭,可省略第一個(gè)索引
numbers[:3]
# 復(fù)制整個(gè)序列,可將兩個(gè)索引都省略
numbers[:]
[8, 9, 10]
[1, 2, 3]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numbers[0:10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 默認(rèn)步長(zhǎng)為1
numbers[0:10:2]
# 要從序列中每隔3個(gè)元素提取1個(gè),只需提供步長(zhǎng)4即可
numbers[::4]
[1, 3, 5, 7, 9]
# 步長(zhǎng)不能為0,否則無(wú)法向前移動(dòng),但可以為負(fù)數(shù),即從右向左提取元素
numbers[8:3:-1]
numbers[10:0:-2]
numbers[0:10:-2]
numbers[::-2]
[9, 8, 7, 6, 5]
[10, 8, 6, 4, 2]
[]
[10, 8, 6, 4, 2]
numbers[5::-2]
numbers[:5:-2]
[6, 4, 2]
[10, 8]
列表方法
部分方法在《順序表與單鏈表》那篇文章有涉及,這里復(fù)述下
append
方法append用于將一個(gè)對(duì)象附加到列表末尾。
lst = [1, 2, 3]
# append直接修改原有的列表
lst.append(4)
lst
[1, 2, 3, 4]
clear 方法clear就地清空列表的內(nèi)容。
lst = [1, 2, 3]
lst.clear()
lst
# 等價(jià)于lst[:] = []
[]
copy 方法 copy 復(fù)制列表,常規(guī)復(fù)制只是將另一個(gè)名稱關(guān)聯(lián)到列表。
a = [1, 2, 3]
b = a
b[1] = 4
a
[1, 4, 3]
要讓a和b指向不同的列表,就必須將b關(guān)聯(lián)到a的副本
a = [1, 2, 3]
b = a.copy()
b[1] = 4
a
# 這類似于使用a[:]或list(a),它們也都復(fù)制a
[1, 2, 3]
count
方法count計(jì)算指定的元素在列表中出現(xiàn)了多少次
['to', 'be', 'or', 'not', 'to', 'be'].count('to')
x = [[1, 2], 1, 1, [2, 1, [1, 2]]]
x.count(1)
x.count([1, 2])
2
2
1
5. extend
方法extend讓你能夠同時(shí)將多個(gè)值附加到列表末尾,為此可將這些值組成的序列作為參數(shù)提
供給方法extend。換而言之,你可使用一個(gè)列表來(lái)擴(kuò)展另一個(gè)列表。
a = [1, 2, 3]
b = [4, 5, 6]
a.extend(b)
a
[1, 2, 3, 4, 5, 6]
這可能看起來(lái)類似于拼接,但存在一個(gè)重要差別,那就是將修改被擴(kuò)展的序列(這里是a)。在常規(guī)拼接中,情況是返回一個(gè)全新的序列。
a = [1, 2, 3]
b = [4, 5, 6]
a + b
a
[1, 2, 3, 4, 5, 6]
[1, 2, 3]
拼接出來(lái)的列表與前一個(gè)示例擴(kuò)展得到的列表完全相同,但在這里a并沒(méi)有被修 改。如果要獲得類似于下面的效果, 拼接的效率將比extend低
a = a + b
拼接操作不會(huì)修改原來(lái)的列表。要獲得與extend相同的效果, 可將列表賦給切片,
a = [1, 2, 3]
b = [4, 5, 6]
a[len(a):] = b
a
[1, 2, 3, 4, 5, 6]
index
方法index在列表中查找指定值第一次出現(xiàn)的索引。
knights = ['We', 'are', 'the', 'knights', 'who', 'say', 'ni']
knights.index('who')
4
insert
方法insert用于將一個(gè)對(duì)象插入列表。
numbers = [1, 2, 3, 5, 6, 7]
numbers.insert(3, 'four')
numbers
[1, 2, 3, 'four', 5, 6, 7]
與extend一樣,也可使用切片賦值來(lái)獲得與insert一樣的效果。
numbers = [1, 2, 3, 5, 6, 7]
numbers[3:3] = ['four']
numbers
[1, 2, 3, 'four', 5, 6, 7]
pop
方法pop從列表中刪除一個(gè)元素(末尾為最后一個(gè)元素),并返回這一元素。
# pop是唯一既修改列表又返回一個(gè)非None值的列表方法。
x = [1, 2, 3]
x.pop()
x
x.pop(0)
x
3
[1, 2]
1
[2]
remove
方法remove用于刪除第一個(gè)為指定值的元素。remove是就地修改且不返回值的方法之一。不同于pop的是,它修改列表,但不返 回任何值。
x = ['to', 'be', 'or', 'not', 'to', 'be']
x.remove('be')
x
['to', 'or', 'not', 'to', 'be']
reverse
方法reverse按相反的順序排列列表中的元素
x = [1, 2, 3]
x.reverse()
x
[3, 2, 1]
sort
方法sort用于對(duì)列表就地排序。就地排序意味著對(duì)原來(lái)的列表進(jìn)行修改,使其元素按順序 排列,而不是返回排序后的列表的副本。
x = [4, 6, 2, 1, 7, 9]
x.sort()
x
[1, 2, 4, 6, 7, 9]
只改變副本,保留原始列表不變,使用以下方法:
# 方法一
x = [4, 6, 2, 1, 7, 9]
y = x.copy()
y.sort()
x
[4, 6, 2, 1, 7, 9]
# 方法二
x = [4, 6, 2, 1, 7, 9]
y = sorted(x)
# 不能用y = x.sort(),這樣得到y(tǒng)的值為None
x
y
[4, 6, 2, 1, 7, 9]
[1, 2, 4, 6, 7, 9]
實(shí)際上,這個(gè)sorted()函數(shù)可用于任何序列,但總是返回一個(gè)列表
sorted('Python')
['P', 'h', 'n', 'o', 't', 'y']
高級(jí)排序
方法sort接受兩個(gè)可選參數(shù):key和reverse。參數(shù)key類似于參數(shù)cmp:你將其設(shè)置為一個(gè)用于排序的函數(shù)。然而, 不會(huì)直接使用這個(gè)函數(shù)來(lái)判斷一個(gè)元素是否比另一個(gè)元素小,而是使用它來(lái)為每個(gè)元素創(chuàng)建一個(gè) 鍵,再根據(jù)這些鍵對(duì)元素進(jìn)行排序。因此,要根據(jù)長(zhǎng)度對(duì)元素進(jìn)行排序,可將參數(shù)key設(shè)置為函數(shù)len。
x = ['aardvark', 'abalone', 'acme', 'add', 'aerate']
x.sort(key=len)
x
['add', 'acme', 'aerate', 'abalone', 'aardvark']
對(duì)于另一個(gè)關(guān)鍵字參數(shù)reverse,只需將其指定為一個(gè)真值,以指出是否要按相反的順序?qū)α斜磉M(jìn)行排序。
x = [4, 6, 2, 1, 7, 9]
x.sort(reverse=True)
x
[9, 7, 6, 4, 2, 1]
函數(shù)sorted也接受參數(shù)key和reverse。在很多情況下,將參數(shù)key設(shè)置為一個(gè)自定義函數(shù)很有 用。
列表生成式
簡(jiǎn)稱“生成列表的公式”,通常含有自定義的變量
[x * x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[x*x for x in range(10) if x%3 == 0]
[0, 9, 36, 81]
還可添加更多的for部分。
[(x, y) for x in range(3) for y in range(3)]
# 等價(jià)于
result = []
for x in range(3):
for y in range(3):
result.append((x, y))
result
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
元組
與列表一樣,元組也是序列,唯一的差別在于元組是不能修改的這一點(diǎn)和字符串 一樣的。元組語(yǔ)法很簡(jiǎn)單,只要將一些值用逗號(hào)分隔,就能自動(dòng)創(chuàng)建一個(gè)元組。
1, 2, 3
# 也可以用圓括號(hào)創(chuàng)建
(1, 2, 3)
(1, 2, 3)
(1, 2, 3)
# 只包含一個(gè)值的元組
42,
(42,)
函數(shù)tuple的工作原理與list很像:它將一個(gè)序列作為參數(shù),并將其轉(zhuǎn)換為元組。如果參數(shù) 已經(jīng)是元組,就原封不動(dòng)地返回它。
tuple([1, 2, 3])
tuple('abc')
tuple((1, 2, 3))
(1, 2, 3)
('a', 'b', 'c')
(1, 2, 3)
元組的創(chuàng)建及其元素的訪問(wèn)方式與其他序列相同
x = 1, 2, 3
x[1]
x[0:2]
2
(1, 2)
元組是可以迭代的對(duì)象,所以可以用for...in進(jìn)行遍歷
tp = tuple('abc')
for i in tp:
print(i,end=",")
a,b,c,
字符串
在python中字符串是基本的數(shù)據(jù)的類型,是一個(gè)不可變的字符序列
格式化字符串
格式化字符串的兩種方法:
%做占位符 {}做占位符 f-string
name = 'J'
age = 20
"我叫%s,今年%d" %(name,age)
"我叫{0},今年{1}".format(name,age)
f"我叫{name},今年{age}"
'我叫J,今年20'
'我叫J,今年20'
'我叫J,今年20'
在format格式化時(shí),可使用* 或者 ** 進(jìn)行對(duì)list、tuple拆分
foods = ['fish', 'beef', 'fruit']
'i like eat {} and {} and {}'.format(*foods)
'i like eat fish and beef and fruit'
寬度、精度和千位分隔符
設(shè)置浮點(diǎn)數(shù)(或其他更具體的小數(shù)類型)的格式時(shí),默認(rèn)在小數(shù)點(diǎn)后面顯示6位小數(shù),并根 據(jù)需要設(shè)置字段的寬度,而不進(jìn)行任何形式的填充。
# 指定寬度,加:
"{num:10}".format(num=3)
"{name:10}".format(name="Bob")
' 3'
'Bob '
# 精度也是使用整數(shù)指定的,但需要在它前面加上一個(gè)表示小數(shù)點(diǎn)的句點(diǎn)
"Pi is {pi:.2f}".format(pi=3.1415926)
'Pi is 3.14'
# 同時(shí)指定寬度和精度。
"{pi:10.2f}".format(pi=3.1415926)
' 3.14'
# 對(duì)于其他類型也可指定精度,但是這樣做的情形不太常見(jiàn)
"{:.5}".format("Hello World")
'Hello'
# 使用逗號(hào)添加千位分隔符
'{:,}'.format(12345678900000)
'{:30,}'.format(12345678900000)
'{:,.2f}'.format(12345678900000)
'12,345,678,900,000'
' 12,345,678,900,000'
'12,345,678,900,000.00'
對(duì)其和填充
在一欄中同時(shí)包含字符串和數(shù)時(shí),可以修改默認(rèn)對(duì)齊方式。方法是在指定寬 度和精度的數(shù)前面,添加一個(gè)標(biāo)志,這個(gè)標(biāo)志可以是零、加號(hào)、減號(hào)或空格
'{:010.2f}'.format(3.1415926)
'{:-10.2f}'.format(3.1415926)
'{:+10.2f}'.format(3.1415926)
'0000003.14'
' 3.14'
' +3.14'
要指定左對(duì)齊、右對(duì)齊和居中,可分別使用<、 >和^
print('{0:<10.2f}\n{0:^10.2f}\n{0:>10.2f}'.format(3.1415926))
3.14
3.14
3.14
可以使用填充字符來(lái)擴(kuò)充對(duì)齊說(shuō)明符,這樣將使用指定的字符而不是默認(rèn)的空格來(lái)填充
"{:¥^15}".format(" WIN BIG ")
'¥¥¥ WIN BIG ¥¥¥'
還有更具體的說(shuō)明符=,它指定將填充字符放在符號(hào)和數(shù)字之間
print('{0:10.2f}\n{1:10.2f}'.format(3.1415926, -3.1415926))
print('{0:10.2f}\n{1:=10.2f}'.format(3.1415926, -3.1415926))
3.14
-3.14
3.14
- 3.14
如果要給正數(shù)加上符號(hào),可使用說(shuō)明符+,默認(rèn)是-
pi = 3.1415926
print('{0:-.2}\t{1:-.2}'.format(pi, -pi))
print('{0:.2}\t{1:.2}'.format(pi, -pi))
print('********************')
print('{0:+.2}\t{1:.2}'.format(pi, -pi))
# 如果將符號(hào)說(shuō)明符指定為空格,會(huì)在正數(shù)前面加上空格
print('{0: .2}\t{1: .2}'.format(pi, -pi))
3.1 -3.1
3.1 -3.1
********************
+3.1 -3.1
3.1 -3.1
字符串編碼
將字符串轉(zhuǎn)化為指定類型的數(shù)據(jù)格式
"The number is {num}".format(num=42)
# 二進(jìn)制轉(zhuǎn)換
"The number is {num:b}".format(num=42)
"The number is {num:#b}".format(num=42)
# 八進(jìn)制轉(zhuǎn)換
"The number is {num:o}".format(num=42)
"The number is {num:#o}".format(num=42)
# 十進(jìn)制轉(zhuǎn)換
"The number is {num:d}".format(num=42)
# 使用科學(xué)表示法來(lái)表示小數(shù)
"The number is {num:e}".format(num=pi)
# 將整數(shù)解讀為Unicode碼點(diǎn)
"The number is {num:c}".format(num=97)
'The number is 42'
'The number is 101010'
'The number is 0b101010'
'The number is 52'
'The number is 0o52'
'The number is 42'
'The number is 3.141593e+00'
'The number is a'
字符串方法
前面介紹了列表的方法,而字符串的方法要多得多,因?yàn)槠浜芏喾椒ǘ际菑哪Kstring那里 繼承而來(lái)的。有關(guān)模塊string的詳細(xì)內(nèi)容見(jiàn)https://docs.python.org/3/library/string.html
1.center
方法center通過(guò)在兩邊添加填充字符(默認(rèn)為空格)讓字符串居中
"The Middle by Jimmy Eat World".center(39)
"The Middle by Jimmy Eat World".center(39, "*")
' The Middle by Jimmy Eat World '
'*****The Middle by Jimmy Eat World*****'
2.find
方法find在字符串中查找子串。如果找到,就返回子串的第一個(gè)字符的索引,否則返回-1
'With a moo-moo here, and a moo-moo there'.find('moo')
title = "Monty Python's Flying Circus"
title.find('Monty')
title.find('Python')
title.find('Flying')
title.find('Zirquss')
7
0
6
15
-1
還可指定搜索的起點(diǎn)和終點(diǎn)
subject = '$$$ Get rich now!!! $$$'
subject.find('$$$')
subject.find('$$$', 1) # 只指定了起點(diǎn)
subject.find('!!!')
subject.find('!!!', 0, 16) # 同時(shí)指定了起點(diǎn)和終點(diǎn)
0
20
16
-1
3.join和split
join是一個(gè)非常重要的字符串方法,其作用與split相反,用于合并序列的元素
seq = [1, 2, 3, 4, 5]
"+".join(seq) # 嘗試合并一個(gè)數(shù)字列表
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-de9959aa34e6> in <module>()
1 seq = [1, 2, 3, 4, 5]
----> 2 "+".join(seq) # 嘗試合并一個(gè)數(shù)字列表
TypeError: sequence item 0: expected str instance, int found
seq = ['1', '2', '3', '4', '5']
"+".join(seq) # 合并一個(gè)字符串列表
'1+2+3+4+5'
'1+2+3+4+5'.split("+")
'1+2+3+4+5'.split("+",1) # 返回兩個(gè)參數(shù)列表
['1', '2', '3', '4', '5']
['1', '2+3+4+5']
注意,如果沒(méi)有指定分隔符,將默認(rèn)在單個(gè)或多個(gè)連續(xù)的空白字符(空格、制表符、換行符 等)處進(jìn)行拆分。
lower
方法lower返回字符串的小寫(xiě)版本。
'Trondheim Hammer Dance'.lower()
'trondheim hammer dance'
replace
方法replace將指定子串都替換為另一個(gè)字符串,并返回替換后的結(jié)果
'This is a test'.replace('is', 'eez')
'Theez eez a test'
5.strip
方法strip將字符串開(kāi)頭和末尾的空白(但不包括中間的空白)刪除,并返回刪除后的結(jié)果
' internal whitespace is kept '.strip()
'internal whitespace is kept'
還可在一個(gè)字符串參數(shù)中指定要?jiǎng)h除哪些字符
'*** SPAM * for * everyone!!! ***'.strip(' *!')
'SPAM * for * everyone'
這個(gè)方法只刪除開(kāi)頭或末尾的指定字符,因此中間的星號(hào)未被刪除。
translate
方法translate與replace一樣替換字符串的特定部分,但不同的是它只能進(jìn)行單字符替換。這個(gè)方法的優(yōu)勢(shì)在于能夠同時(shí)替換多個(gè)字符,因此效率比replace高。
使用translate前必須創(chuàng)建一個(gè)轉(zhuǎn)換表。這個(gè)轉(zhuǎn)換表指出了不同Unicode碼點(diǎn)之間的轉(zhuǎn) 換關(guān)系。要?jiǎng)?chuàng)建轉(zhuǎn)換表,可對(duì)字符串類型str調(diào)用方法maketrans,這個(gè)方法接受兩個(gè)參數(shù):兩個(gè) 長(zhǎng)度相同的字符串,它們指定要將第一個(gè)字符串中的每個(gè)字符都替換為第二個(gè)字符串中的相應(yīng)字 符。
table = str.maketrans('cs', 'kz')
可查看轉(zhuǎn)換表的內(nèi)容,看到的只是Unicode碼點(diǎn)之間的映射
table
{99: 107, 115: 122}
'this is an incredible test'.translate(table)
'thiz iz an inkredible tezt'
調(diào)用方法maketrans時(shí),還可提供可選的第三個(gè)參數(shù),指定要將哪些字母刪除。
# 將所有空格刪除
table = str.maketrans('cs', 'kz', ' ')
'this is an incredible test'.translate(table)
'thizizaninkredibletezt'
7.判斷字符串是否滿足特定的條件
很多字符串方法都以is打頭,如isalnum、 isalpha、 isdecimal、 isdigit、 isidentifier、 islower、 isnumeric、 isprintable、 isspace、 istitle、 isupper,它們判斷字符串是否具有特定 的性質(zhì)(如包含的字符全為空白、數(shù)字或大寫(xiě))。如果字符串具備特定的性質(zhì),這些方法就返回 True,否則返回False。
"1234".isnumeric()
True
字典
與列表一樣是一個(gè)可變序列 以鍵值對(duì)的方式存儲(chǔ)數(shù)據(jù),字典是一個(gè)無(wú)序的序列
創(chuàng)建字典
1.花括號(hào)創(chuàng)建字典
phonebook = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
phonebook
{'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
2.函數(shù) dict 可使用函數(shù)dict從其他映射(如其他字典)或鍵值對(duì)序列創(chuàng)建字典
items = [('name', 'Gumby'), ('age', 42)]
d = dict(items)
d
d['name']
{'name': 'Gumby', 'age': 42}
'Gumby'
還可使用關(guān)鍵字實(shí)參來(lái)調(diào)用這個(gè)函數(shù)
d = dict(name='Gumby', age=42)
d
{'name': 'Gumby', 'age': 42}
基本的字典操作
字典的基本行為在很多方面都類似于序列。
len(d)返回字典d包含的項(xiàng)(鍵值對(duì))數(shù)。 d[k]返回與鍵k相關(guān)聯(lián)的值。 d[k] = v將值v關(guān)聯(lián)到鍵k。 del d[k]刪除鍵為k的項(xiàng)。 k in d檢查字典d是否包含鍵為k的項(xiàng)。
將字符串格式設(shè)置功能用于字典
可在字典中包含各種信息,這樣只需在格式字符串中提取所需的信息即可。為此, 必須使用format_map來(lái)指出你將通過(guò)一個(gè)映射來(lái)提供所需的信息。
phonebook
"Cecil's phone number is {Cecil}.".format_map(phonebook)
{'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
"Cecil's phone number is 3258."
字典方法
clear 方法clear刪除所有的字典項(xiàng),這種操作是就地執(zhí)行的
d = {}
d['name'] = 'Gumby'
d['age'] = 42
d
returned_value = d.clear()
d
print(returned_value)
{'name': 'Gumby', 'age': 42}
{}
None
這為何很有用呢?我們來(lái)看兩個(gè)場(chǎng)景。下面是第一個(gè)場(chǎng)景:
x = {}
y = x
x['key'] = 'value'
y
x = {}
x
y
{'key': 'value'}
{}
{'key': 'value'}
下面是第二個(gè)場(chǎng)景:
x = {}
y = x
x['key'] = 'value'
y
x.clear()
x
y
{'key': 'value'}
{}
{}
在這兩個(gè)場(chǎng)景中, x和y最初都指向同一個(gè)字典。在第一個(gè)場(chǎng)景中,通過(guò)將一個(gè)空字典賦 給x來(lái)“清空”它。這對(duì)y沒(méi)有任何影響,它依然指向原來(lái)的字典。但要?jiǎng)h除原來(lái)字典的所有元素,必須使用clear,這樣做的話y也將是空的
copy
方法copy返回一個(gè)新字典,其包含的鍵值對(duì)與原來(lái)的字典相同(這個(gè)方法執(zhí)行的是淺復(fù)制, 因?yàn)橹当旧硎窃?,而非副本)?/p>
x = {'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
y = x.copy()
y['username'] = 'mlh'
y['machines'].remove('bar')
y
{'username': 'mlh', 'machines': ['foo', 'baz']}
x
{'username': 'mlh', 'machines': ['foo', 'baz']}
{'username': 'mlh', 'machines': ['foo', 'baz']}
{'username': 'admin', 'machines': ['foo', 'baz']}
可以看出,當(dāng)替換副本中的值時(shí),原件不受影響。然而,如果修改副本中的值(就地修改而 不是替換),原件也將發(fā)生變化,因?yàn)樵赶虻囊彩潜恍薷牡闹?/p>
為避免這種問(wèn)題,一種辦法是執(zhí)行深復(fù)制,即同時(shí)復(fù)制值及其包含的所有值。為此, 可使用模塊copy中的函數(shù)deepcopy。
from copy import deepcopy
d = {}
d['names'] = ['Alfred', 'Bertrand']
c = d.copy()
dc = deepcopy(d)
d['names'].append('Clive')
c
dc
{'names': ['Alfred', 'Bertrand', 'Clive']}
{'names': ['Alfred', 'Bertrand']}
fromkeys
方法fromkeys創(chuàng)建一個(gè)新字典,其中包含指定的鍵,且每個(gè)鍵對(duì)應(yīng)的值都是None。
{}.fromkeys(['name', 'age'])
{'name': None, 'age': None}
這個(gè)示例首先創(chuàng)建了一個(gè)空字典,再對(duì)其調(diào)用方法fromkeys來(lái)創(chuàng)建另一個(gè)字典,這顯得有點(diǎn) 多余??梢圆贿@樣做,而是直接對(duì)dict調(diào)用方法fromkeys。
dict.fromkeys(['name', 'age'])
{'name': None, 'age': None}
如果不想使用默認(rèn)值None,可提供特定的值
dict.fromkeys(['name', 'age'], '(unknown)')
{'name': '(unknown)', 'age': '(unknown)'}
get
方法get為訪問(wèn)字典項(xiàng)提供了更加靈活的方法。通常,如果你試圖訪問(wèn)字典中沒(méi)有的項(xiàng),將引發(fā) 錯(cuò)誤。
d = {}
print(d['name'])
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-21-c92ea8278836> in <module>()
1 d = {}
----> 2 print(d['name'])
KeyError: 'name'
而使用get不會(huì)這樣:
print(d.get('name'))
None
使用get來(lái)訪問(wèn)不存在的鍵時(shí),沒(méi)有引發(fā)異常,而是返回None。還可指定“默認(rèn)” 值,這樣將返回指定的值而不是None。
d.get('name', 'N/A')
'N/A'
items
方法items返回一個(gè)包含所有字典項(xiàng)的列表,其中每個(gè)元素都為(key, value)的形式。字典項(xiàng) 在列表中的排列順序不確定。
d = {'title': 'Python Web Site', 'url': 'http://www.python.org', 'spam': 0}
d.items()
dict_items([('title', 'Python Web Site'), ('url', 'http://www.python.org'), ('spam', 0)])
返回值屬于一種名為字典視圖的特殊類型。字典視圖可用于迭代,還可確定其長(zhǎng)度以及對(duì)其執(zhí)行成員資格檢查。
it = d.items()
len(it)
('spam', 0) in it
3
True
d['spam'] = 1
it
d['spam'] = 0
it
dict_items([('title', 'Python Web Site'), ('url', 'http://www.python.org'), ('spam', 1)])
False
dict_items([('title', 'Python Web Site'), ('url', 'http://www.python.org'), ('spam', 0)])
True
# 將字典項(xiàng)復(fù)制到列表中
list(d.items())
[('title', 'Python Web Site'), ('url', 'http://www.python.org'), ('spam', 0)]
keys
方法keys返回一個(gè)字典視圖,其中包含指定字典中的鍵。
d.keys()
dict_keys(['title', 'url', 'spam'])
pop
方法pop可用于獲取與指定鍵相關(guān)聯(lián)的值,并將該鍵值對(duì)從字典中刪除。
d = {'x': 1, 'y': 2}
d.pop('x')
d
1
{'y': 2}
popitem
方法popitem類似于list.pop,但list.pop彈出列表中的最后一個(gè)元素,而popitem隨機(jī)地彈 出一個(gè)字典項(xiàng),因?yàn)樽值漤?xiàng)的順序是不確定的,沒(méi)有“最后一個(gè)元素”的概念。
d = {'url': 'http://www.python.org', 'spam': 0, 'title': 'Python Web Site'}
d.popitem()
d
('title', 'Python Web Site')
{'url': 'http://www.python.org', 'spam': 0}
setdefault
方法setdefault有點(diǎn)像get,因?yàn)樗搏@取與指定鍵相關(guān)聯(lián)的值,但除此之外, setdefault 還在字典不包含指定的鍵時(shí),在字典中添加指定的鍵值對(duì)。
d = {}
d.setdefault('name', 'N/A')
d
d['name'] = 'Gumby'
d.setdefault('name')
d
'N/A'
{'name': 'N/A'}
'Gumby'
{'name': 'Gumby'}
如上,指定的鍵不存在時(shí), setdefault返回指定的值并相應(yīng)地更新字典。如果指定的鍵 存在,就返回其值,并保持字典不變。與get一樣,值是可選的;如果沒(méi)有指定,默認(rèn)為None。
d = {}
print(d.setdefault('name'))
d
None
{'name': None}
update
方法update使用一個(gè)字典中的項(xiàng)來(lái)更新另一個(gè)字典
d = {
'title': 'Python Web Site',
'url': 'http://www.python.org',
'changed': 'Mar 14 22:09:15 MET 2016'
}
x = {'title': 'Python Language Website'}
d.update(x)
d
{'title': 'Python Language Website',
'url': 'http://www.python.org',
'changed': 'Mar 14 22:09:15 MET 2016'}
對(duì)于通過(guò)參數(shù)提供的字典,將其項(xiàng)添加到當(dāng)前字典中。如果當(dāng)前字典包含鍵相同的項(xiàng),就替 換它。可像函數(shù)dict那樣調(diào)用方法update。這意味著調(diào)用 update時(shí),可向它提供一個(gè)映射、一個(gè)由鍵值對(duì)組成的序列或關(guān)鍵字參數(shù)
values
方法values返回一個(gè)由字典中的值組成的字典視圖。不同于方法keys,方法values返回的視 圖可能包含重復(fù)的值
d = {}
d[1] = 1
d[2] = 2
d[3] = 3
d[4] = 1
d.values()
dict_values([1, 2, 3, 1])
字典生成式
在列表生成式中, for前面只有一個(gè)表達(dá)式,而在字典生成式中, for前面有兩個(gè)用冒號(hào)分隔的表 達(dá)式,這兩個(gè)表達(dá)式分別為鍵及其對(duì)應(yīng)的值
items = ["fruits","books","others"]
prices = [96,78,88]
d = {item:price for item,price in zip(items,prices)}
d
{'fruits': 96, 'books': 78, 'others': 88}
squares = {i:"{} squared is {}".format(i, i**2) for i in range(10)}
squares
{0: '0 squared is 0',
1: '1 squared is 1',
2: '2 squared is 4',
3: '3 squared is 9',
4: '4 squared is 16',
5: '5 squared is 25',
6: '6 squared is 36',
7: '7 squared is 49',
8: '8 squared is 64',
9: '9 squared is 81'}
集合
集合是python語(yǔ)言提供的內(nèi)置數(shù)據(jù)結(jié)構(gòu),與列表,字典一樣屬于可變類型的數(shù)列,集合實(shí)際上是沒(méi)有value的字典
創(chuàng)建集合
使用{}
s = {"python","hello","99"}
s
{'99', 'hello', 'python'}
使用內(nèi)置函數(shù)set()
set(range(5))
# 集合中沒(méi)有相同的元素
set([1,2,2,3])
# 集合中的元素時(shí)無(wú)序的
set("python")
{0, 1, 2, 3, 4}
{1, 2, 3}
{'h', 'n', 'o', 'p', 't', 'y'}
集合方法
in或者not in
用來(lái)判斷元素是否在集合中
s = {10,20,30,123,1}
10 in s
10 not in s
True
False
add()
添加元素
s.add(80)
s
{1, 10, 20, 30, 80, 123}
3.update()
至少添加一個(gè)元素
s.update([1,2,3])
s
s.update((4,5,6))
s
{1, 2, 3, 10, 20, 30, 80, 123}
{1, 2, 3, 4, 5, 6, 10, 20, 30, 80, 123}
remove()
一次刪除一個(gè)指定的元素
s.remove(1)
s
{2, 3, 4, 5, 6, 10, 20, 30, 80, 123}
s.remove(99)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-32-a73c41416d4a> in <module>()
----> 1 s.remove(99)
KeyError: 99
discard()
一次刪除一個(gè)指定的元素,如果指定的元素不存在,不拋出異常
s.discard(99)
s
{2, 3, 4, 5, 6, 10, 20, 30, 80, 123}
pop()
一次只刪除一個(gè)任意元素
s.pop()
2
s.pop()
s
3
{4, 5, 6, 10, 20, 30, 80, 123}
clear()
清空集合
s.clear()
s
set()
==或者!=
判斷兩個(gè)集合是否相等
s1 = {1,2,3,4,5}
s2 = {3,4,5,6,7}
s1 == s2
s1 != s2
False
True
issubset()
一個(gè)集合是否是另一個(gè)集合的子集
s1 = {1,2,3,4,5}
s2 = {3,4,5}
s3 = {3,4,5,6}
s2.issubset(s1)
s3.issubset(s1)
True
False
issuperset
一個(gè)集合是否是另一個(gè)集合的超集
s1 = {1,2,3,4,5}
s2 = {3,4,5}
s3 = {3,4,5,6}
s1.issuperset(s2)
s1.issuperset(s3)
True
False
isdisjoint()
兩個(gè)集合是否沒(méi)有交集
s2 = {3,4,5}
s3 = {3,4,5,6}
s2.isdisjoint(s3)
False
intersection()
求兩個(gè)集合的交集
s1 = {1,2,3,4}
s2 = {2,3,4,5,6}
s1.intersection(s2)
# &與intersection()等價(jià)
s1 & s2
{2, 3, 4}
{2, 3, 4}
union()
求兩個(gè)集合的并集
s1 = {1,2,3,4}
s2 = {2,3,4,5,6}
s1.union(s2)
# |與union()等價(jià)
s1 | s2
{1, 2, 3, 4, 5, 6}
{1, 2, 3, 4, 5, 6}
difference()
求兩個(gè)集合的差集
s1 = {1,2,3,4}
s2 = {2,3,4,5,6}
s1.difference(s2)
# -與difference()等價(jià)
s1 - s2
{1}
{1}
symmetric_difference()
求兩個(gè)集合的對(duì)稱差集
s1 = {1,2,3,4}
s2 = {2,3,4,5,6}
s1.symmetric_difference(s2)
# ^與symmetric_difference()等價(jià)
s1 ^ s2
{1, 5, 6}
{1, 5, 6}
集合生成式
將{}改為[]就是列表生成式 沒(méi)有元組生成式
s = {i*i for i in range(6)}
print(s,type(s))
{0, 1, 4, 9, 16, 25} <class 'set'>
也可以加一下老胡的微信 圍觀朋友圈~~~
推薦閱讀
(點(diǎn)擊標(biāo)題可跳轉(zhuǎn)閱讀)
深度學(xué)習(xí)的四個(gè)學(xué)習(xí)階段!
2021年,機(jī)器學(xué)習(xí)研究風(fēng)向要變了?
【機(jī)器學(xué)習(xí)】隨機(jī)森林是我最喜歡的模型
Python之父:Python 4.0可能不會(huì)來(lái)了
老鐵,三連支持一下,好嗎?↓↓
