字典、集合及序列
-
- 字典
-
- 可變類型與不可變類型
- 建立字典的幾種方法
- 内置BIF
- 課後習題
- 集合
-
- 集合的建立
- 集合的内置方法
- 不可變集合
- 序列
-
- Iterable對象的說明和相關内置函數
字典
可變類型與不可變類型
- 序列是以連續的整數為索引,與此不同的是,字典以"關鍵字"為索引,關鍵字可以是任意不可變類型,通常用字元串或數值。
- 字典是 Python 唯一的一個 映射類型,字元串、元組、清單屬于序列類型。
那麼如何快速判斷一個資料類型
X
是不是可變類型的呢?兩種方法:
- 麻煩方法:用
函數,對 X 進行某種操作,比較操作前後的id(X)
,如果不一樣,則id
不可變,如果一樣,則X
可變。X
- 便捷方法:用
,隻要不報錯,證明hash(X)
可被哈希,即不可變,反過來不可被哈希,即可變。X
【例子】
i = 1
print(id(i)) # 140732167000896
i = i + 2
print(id(i)) # 140732167000960
l = [1, 2]
print(id(l)) # 4300825160
l.append('Python')
print(id(l)) # 4300825160
- 整數
在加 1 之後的i
和之前不一樣,是以加完之後的這個id
(雖然名字沒變),但不是加之前的那個i
了,是以整數是不可變類型。i
- 清單
在附加l
之後的'Python'
和之前一樣,是以清單是可變類型。id
【例子】
print(hash('Name')) # -9215951442099718823
print(hash((1, 2, 'Python'))) # 823362308207799471
print(hash([1, 2, 'Python']))
# TypeError: unhashable type: 'list'
print(hash({1, 2, 3}))
# TypeError: unhashable type: 'set'
- 數值、字元和元組 都能被哈希,是以它們是不可變類型。
- 清單、集合、字典不能被哈希,是以它是可變類型。
建立字典的幾種方法
a = dict(one=1, two=2, three=3) #dict(**(kwargs)),keyword隻能是字元串,但不需要加引号
b = {'one': 1, 'two': 2, 'three': 3}
c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
d = dict([('two', 2), ('one', 1), ('three', 3)]) #建立字典的方法,dict隻有一個參數,是以用元組/清單框起來
e = dict({'three': 3, 'one': 1, 'two': 2})
dict1 = dict((('F',70),('i',105),('s',115))) #建立字典的方法,dict隻有一個參數,是以用元組框起來
dict2 = dict(小甲魚 = '讓程式設計改變世界',蒼井空 = '讓A片征服宅男') #關鍵字參數,建立字典
#keyword不能是字元串
dict2['蒼井空'] = '老了' #改變鍵的值
内置BIF
dict.fromkeys(seq[,value]) #在原字典的基礎上建立和傳回新的字典,以seq中的各元素作為字典的鍵,以value作為字典的值,值預設為None
#通路字典的方法
dict.keys() #傳回一個iterable,可以用list()轉換為字典鍵的清單
dict.values() #傳回一個iterable,可以用list()轉換為字典值的清單
dict.items() #傳回一個iterable,鍵值對用tuple表示
dict.get(key,default = None) #有這個key就傳回這個值,沒有就傳回default的值,預設為None
dict.setdefault(key,default = None) #有這個key就傳回這個值,沒有就添加這個項(key, default)并傳回a
dict.clear() #清空字典
dict.copy() #淺拷貝,與直接指派不同,給對象貼标簽,若對象改變,标簽也改變
dict.pop(key[,default]) #給定鍵,彈出并傳回對應的值(value),若key不存在,則傳回default值
del(dict[key]) #删除字典給定鍵所對應的值
dict.popitem() #彈出最後一個鍵值對(item)
dict.update(dict2) #相當于清單的extend(),把字典參數dict的鍵值對更行到字典dict中
- 字典中幾種拷貝方法的例子
from copy import deepcopy
dic1 = {'user': 'lsgogroup', 'num': [1, 2, 3]}
# 引用對象
dic2 = dic1
# 淺拷貝父對象(一級目錄),子對象(二級目錄)不拷貝,還是引用
dic3 = dic1.copy()
# 深拷貝
dic4 = deepcopy(dic1)
print(id(dic1)) # 148635574728
print(id(dic2)) # 148635574728
print(id(dic3)) # 148635574344
print(id(dic4)) # 和上面不一樣
# 修改 data 資料
dic1['user'] = 'root'
dic1['num'].remove(1)
# 輸出結果
print(dic1) # {'user': 'root', 'num': [2, 3]}
print(dic2) # {'user': 'root', 'num': [2, 3]}
print(dic3) # {'user': 'runoob', 'num': [2, 3]}
print(dic4) # {'user': 'lsgogroup', 'num': [1, 2, 3]}
- 成員資格操作符,運用在鍵中,在字典中查找的是鍵而不是值,而序列中查找的是元素的值而不是索引号
key in dict
課後習題
2、字典中的value
有一個字典,儲存的是學生各個程式設計語言的成績,内容如下
data = {
'python': {'上學期': '90', '下學期': '95'},
'c++': ['95', '96', '97'],
'java': [{'月考':'90', '期中考試': '94', '期末考試': '98'}]
}
各門課程的考試成績存儲方式并不相同,有的用字典,有的用清單,但是分數都是字元串類型,請實作函數
transfer_score(score_dict)
,将分數修改成int類型
def transfer_score(data):
# 暫時沒做出來,占個坑
集合
Python 中
set
與
dict
類似,也是一組
key
的集合,但不存儲
value
。由于
key
不能重複,是以,在
set
中,沒有重複的
key
。
注意,
key
為不可變類型,即可哈希的值。但是
set
是可變類型,與清單、字典相同。
【例子】
num = {}
print(type(num)) # <class 'dict'>
num = {1, 2, 3, 4}
print(type(num)) # <class 'set'>
集合的建立
# 直接建立空集合
basket = set()
# 增加元素
basket.add('1')
# 花括号擴起
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
# 工廠函數轉化set()
a = set('abracadabra')
print(a)
# {'r', 'b', 'd', 'c', 'a'}
b = set(("Google", "Lsgogroup", "Taobao", "Taobao"))
print(b)
# {'Taobao', 'Lsgogroup', 'Google'}
c = set(["Google", "Lsgogroup", "Taobao", "Google"])
print(c)
# {'Taobao', 'Lsgogroup', 'Google'}
集合的内置方法
set1.add(elmnt) # 用于給集合添加元素
set1.update(set) # 用于修改目前集合,可以添加新的元素或集合到目前集合中,如果添加的元素在集合中已存在,則該元素隻會出現一次,重複的會忽略。
x = {"apple", "banana", "cherry"}
y = {"google", "baidu", "apple"}
x.update(y)
print(x)
# {'cherry', 'banana', 'apple', 'google', 'baidu'}
y.update(["lsgo", "dreamtech"])
print(y)
# {'lsgo', 'baidu', 'dreamtech', 'apple', 'google'}
set1.remove(item) # 用于移除集合中的制定元素,若元素不存在,則會發生錯誤
set1.pop(item) # 用于随機移除一個元素
set1.intersection(set2) # 傳回set1 set2的交集
set1.intersection_update(set2) # 同樣的傳回交集,在原始的集合上取交集,沒有傳回值
set1 & set2 # 傳回兩個集合的交集
set1.union(set2) # 傳回兩個集合的并集
set1 | set2 # 傳回兩個集合的并集
set1.difference(set2) # 傳回集合的差集。
set1 - set2 # 傳回集合的差集。
set1.difference_update(set2) # 集合的差集,直接在原來的集合中移除元素,沒有傳回值。
set1.symmetric_difference(set2) # 傳回集合的異或。
set1 ^ set2 # 傳回集合的異或。
set1.symmetric_difference_update(set) # 移除目前集合中在另外一個指定集合相同的元素,并将另外一個指定集合中不同的元素插入到目前集合中。
set1.issubset(set) # 判斷集合是不是被其他集合包含,如果是則傳回 True,否則傳回 False。
set1 <= set2 # 判斷集合是不是被其他集合包含,如果是則傳回 True,否則傳回 False。
set1.issuperset(set) # 用于判斷集合是不是包含其他集合,如果是則傳回 True,否則傳回 False。
set1 >= set2 # 判斷集合是不是包含其他集合,如果是則傳回 True,否則傳回 False。
set1.isdisjoint(set2) # 用于判斷兩個集合是不是不相交,如果是傳回 True,否則傳回 False。
不可變集合
Python 提供了不能改變元素的集合的實作版本,即不能增加或删除元素,類型名叫
frozenset
。需要注意的是
frozenset
仍然可以進行集合操作,隻是不能用帶有
update
的方法。
-
傳回一個當機的集合,當機後集合不能再添加或删除任何元素。frozenset([iterable])
【例子】
a = frozenset(range(10)) # 生成一個新的不可變集合
print(a)
# frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
b = frozenset('lsgogroup')
print(b)
# frozenset({'g', 's', 'p', 'r', 'u', 'o', 'l'})
序列
在 Python 中,序列類型包括字元串、清單、元組、集合和字典,這些序列支援一些通用的操作,但比較特殊的是,集合和字典不支援索引、切片、相加和相乘操作。
Iterable對象的說明和相關内置函數
一類是集合資料類型,如
list
、
tuple
、
dict
、
set
、
str
等(這些都是序列);
一類是
generator
,包括生成器和帶
yield
的generator function。
這些可以直接作用于
for
循環的對象統稱為可疊代對象:
Iterable
可以被
next()
内置函數調用并不斷傳回下一個值的對象稱為疊代器:
Iterator
生成器都是
Iterator
對象,但
list
、
dict
、
str
雖然是
Iterable
,卻不是
Iterator
你可能會問,為什麼
list
、
dict
、
str
等資料類型不是
Iterator
?
這是因為Python的
Iterator
對象表示的是一個資料流,Iterator對象可以被
next()
函數調用并不斷傳回下一個資料,直到沒有資料時抛出
StopIteration
錯誤。可以把這個資料流看做是一個有序序列,但我們卻不能提前知道序列的長度,隻能不斷通過
next()
函數實作按需計算下一個資料,是以
Iterator
的計算是惰性的,隻有在需要傳回下一個資料時它才會計算。
list(iterable) #把一個可疊代對象轉化為清單,沒有參數傳回空清單,有參數傳回疊代後的清單,字元串就是每個字元單獨組成的清單
tuple(iterable) #把一個可疊代對象轉化為元組
len(iterable) #傳回可疊代對象的長度
max() #傳回序列與參數中的最大值,字母就傳回ASCII碼,字元串就傳回字元的ASCII碼
min() #相反
sum(iterble[,start]) #傳回序列iterable與可選參數start的總和,隻有資料類型能實作sum操作
sorted(iterable, key = None(func), reverse = False) #key用來進行元素的比較,隻有一個參數,具體的函數的參數就是取自于可疊代對象中,指定可疊代對象中的一個元素來進行排序,傳回重新排序的清單(這也是與sort的不同點,sort是直接改變清單)
reversed() #同reverse,傳回可疊代對象,可轉化為清單
enumerate(sequence, [start=0]) #每一個值變成添加索引值後的元組,傳回一個疊代器對象,可轉化為清單,strat參數可以調整索引值的初始值
zip(a,b) #講兩個序列裡的數打包成元組,傳回元組對象,可轉化為清單,a/b是序列(清單)
# 如果各個疊代器的元素個數不一緻,則傳回清單長度與最短的對象相同,利用 * 号操作符,可以将元組解壓為清單。
iter(iterable) #傳回一個可疊代對象的疊代器
next(iter(iterable)) #傳回下一個疊代的值,這裡的iterable必須是可疊代對象
sorted()的用法
【例子】
x = [-8, 99, 3, 7, 83]
print(sorted(x)) # [-8, 3, 7, 83, 99]
print(sorted(x, reverse=True)) # [99, 83, 7, 3, -8]
t = ({"age": 20, "name": "a"}, {"age": 25, "name": "b"}, {"age": 10, "name": "c"})
x = sorted(t, key=lambda a: a["age"])
print(x)
# [{'age': 10, 'name': 'c'}, {'age': 20, 'name': 'a'}, {'age': 25, 'name': 'b'}]
zip()的用法
【例子】
a = [1, 2, 3]
b = [4, 5, 6]
c = [4, 5, 6, 7, 8]
zipped = zip(a, b)
print(zipped) # <zip object at 0x000000C5D89EDD88>
print(list(zipped)) # [(1, 4), (2, 5), (3, 6)]
zipped = zip(a, c)
print(list(zipped)) # [(1, 4), (2, 5), (3, 6)]
a1, a2 = zip(*zip(a, b))
print(list(a1)) # [1, 2, 3]
print(list(a2)) # [4, 5, 6]
**python的星号作用,解包與打散,需要在此更新!