Python通用程式設計 - 第三章:資料型別

yitema01發表於2019-04-04

本文是Python通用程式設計系列教程,已全部更新完成,實現的目標是從零基礎開始到精通Python程式語言。本教程不是對Python的內容進行泛泛而談,而是精細化,深入化的講解,共5個階段,25章內容。所以,需要有耐心的學習,才能真正有所收穫。雖不涉及任何框架的使用,但是會對作業系統和網路通訊進行全域性的講解,甚至會對一些開源模組和伺服器進行重寫。學完之後,你所收穫的不僅僅是精通一門Python程式語言,而且具備快速學習其他程式語言的能力,無障礙閱讀所有Python原始碼的能力和對計算機與網路的全面認識。對於零基礎的小白來說,是入門計算機領域並精通一門程式語言的絕佳教材。對於有一定Python基礎的童鞋,相信這套教程會讓你的水平更上一層樓。

一 數字型別

1. 數字型別 int和float

在第一章使用者互動我們給大家介紹了一下基本的資料型別,這一章主要是介紹不同資料型別的使用方法和深入研究

數字型別即變數的值,如age=1818則是我們儲存的資料。
變數的是用來反映/保持狀態以及狀態變化的,毫無疑問針對不同的狀態就應該用不同型別的資料去標識
複製程式碼

數字型別只能存一個值,是不可變型別(不可變型別可以雜湊,後面章節會講解雜湊)

#int整型
定義:age=10  # age=int(10)
用於標識:年齡,等級,身份證號,qq號,個數
#float浮點型
定義:salary=3.1 #salary=float(3.1)
用於標識:工資,身高,體重,
複製程式碼

2. int型別常用的方法

# 常用操作+內建的方法
print(bin(3)) #十進位制轉成二進位制,0b11
print(oct(8)) #十進位制轉成八進位制,0o10
print(10) #10
print(hex(16)) #十進位制轉成十六進位制,0x10
複製程式碼

在進行使用者互動程式的時候我們常用 .isdigit()這個判斷使用者輸入是不是數字,來進行下一步操作,這樣就避免了程式出錯,但是需要注意的是使用者輸入的內容預設是字串,判斷一個字串是否是數字,我們使用這個方法。

age = input(your age>>:)
if age.isdigit():
    age = int(age)
    age +=1 
print(age)
複製程式碼

3. Python其他數字型別(瞭解)

#int(整型)32位機器上,整數的位數為32位,取值範圍為-2**312**31-1,即-2147483648214748364764位系統上,整數的位數為64位,取值範圍為-2**632**63-1,即-92233720368547758089223372036854775807
#long(長整型)
跟C語言不同,Python的長整數沒有指定位寬,即:Python沒有限制長整數數值的大小,但實際上由於機器記憶體有限,我們使用的長整數數值不可能無限大。
注意,自從Python2.2起,如果整數發生溢位,Python會自動將整數資料轉換為長整數,所以如今在長整數資料後面不加字母L也不會導致嚴重後果了。
注意:在Python3裡不再有long型別了,全都是int
>>> a= 2**64
>>> type(a)  #type()是檢視資料型別的方法
<type 'long'>
>>> b = 2**60
>>> type(b)
<type 'int'>
#complex複數型
>>> x=1-2j
>>> x.imag
-2.0
>>> x.real
1.0
複製程式碼

二 字串型別

1. 字串型別介紹

在python中,加了引號的字元就是字串型別,用於標識:描述性的內容,如姓名,性別,國籍,種族,定義形式:

name='Albert' # name=str('Albert') 
複製程式碼

字串格式化:

name = input('請輸入名字>>:')
print('你好,%s' % name)
複製程式碼

2. 單引號,雙引號和三引號的區別

#那單引號、雙引號、多引號有什麼區別呢? 讓我大聲告訴你,單雙引號木有任何區別,只有下面這種情況 你需要考慮單雙的配合
msg = "My name is Albert , I'm 18 years old!"
#多引號什麼作用呢?作用就是多行字串必須用多引號
msg = 
'''
今天我想寫首小詩,
歌頌我的同桌,
你看他那烏黑的短髮,
好像一隻炸毛雞。
'''
print(msg)
# 三引號裡面寫多行內容
複製程式碼

3. 字串的拼接

#數字可以進行加減乘除等運算,字串呢?讓我大聲告訴你,也能?what ?是的,但只能進行"相加"和"相乘"運算。
>>> name='albert'
>>> age='18'
>>> name+age #相加其實就是簡單拼接
'albert18'
>>> name*5 
'albertalbertalbertalbertalbert'
#注意1:
字串1+字串3,並不會在字串1的基礎上加字串2,而是申請一個全新的記憶體空間存入字串1和字串3,相當字串1與字串3的空間被複制了一次,
#注意2:只能字串加字串,不能字串加其他型別
字串拼接(只能在字串之間進行,且只能相加或相乘)
複製程式碼

字串型別只能存一個值,是不可變型別,可以雜湊。

4. 字串型別常用的方法

(1) 按照索引取值

字串是不可變型別,並不能改變字串的值,取值時最多可以有三個引數,分別是起始位置,結束為止和步長,可以正向取值,反向取值(起始位置大於結束位置或者沒有起始位置與結束位置,步長為-1表示從最後一個開始,步長為負數)

hobbies = "music basketball"
print(hobbies[0])
print(hobbies[1])
print(hobbies[5])
print(hobbies[0:5])
print(hobbies[:5])
print(hobbies[0:5:2])
print(hobbies[0:5:-2])
print(hobbies[11:5:-2])
print(hobbies[-1])
print(hobbies[-2])
複製程式碼

(2) 長度運算

print(len('name'))
複製程式碼

(3) 成員運算

print('a' in 'Albert')
# False
print('a' in not 'Albert')
# True
複製程式碼

(4) 移除空白

print('   name'.lstrip())  # 移除左邊空白
print('name  '.rstrip())  # 移除右邊空白
print('  name  '.strip())  # 移除兩邊空白
複製程式碼

(5) 切分

print('n a me'.split(','))
print('n,a me'.split(','))
print('n,/a /me'.split('/',1)) # 數字表示切割次數,預設全部切割
print('n,a /me'.split('/'))
print('a|b|c'.rsplit('|',1)) # 從右邊開始切割
複製程式碼

(6) 組合

print('a'.join('1234'))
print('a'.join('bcde'))
tag = ' '
print(tag.join(['I', 'say', 'hello', 'world']))  # 可迭代物件必須都是字串
複製程式碼

(7) 替換

print('abc name id'.replace('a', 'card')) 
name = 'albert say :i have a dream,my name is albert'
# 注意此時name原來的值並沒有改變,而是產生了一個替換之後新的值
print(name.replace('albert', 'Albert', 1))   
複製程式碼

(8) 字串其他操作

# find,rfind,index,rindex,count
name='albert say hello'
print(name.find('o',1,3))  # 顧頭不顧尾,找不到則返回-1不會報錯,找到了則顯示索引
# print(name.index('e',2,4))  # 同上,但是找不到會報錯
print(name.count('e',1,3))  # 顧頭不顧尾,如果不指定範圍則查詢所有
# center,ljust,rjust,zfill
name='albert'
print(name.center(30,'-'))
print(name.ljust(30,'*'))
print(name.rjust(30,'*'))
print(name.zfill(50))  # 用0填充

# expandtabs
name='albert\thello'
print(name)
print(name.expandtabs(1))

# captalize,swapcase,title
print(name.capitalize())  # 首字母大寫
print(name.swapcase())  # 大小寫翻轉
msg='albert say hi'
print(msg.title())  # 每個單詞的首字母大寫

# is數字系列
# 在python3中
num1=b'4'  # bytes
num2=u'4'  # unicode,python3中無需加u就是unicode
num3='四'  # 中文數字
num4='Ⅳ' #羅馬數字

# isdigit:bytes,unicode
print(num1.isdigit())  # True
print(num2.isdigit())  # True
print(num3.isdigit())  # False
print(num4.isdigit())  # False

# isdecimal:uncicode
# bytes型別無isdecimal方法
print(num2.isdecimal())  # True
print(num3.isdecimal())  # False
print(num4.isdecimal())  # False

# isnumberic:unicode,中文數字,羅馬數字
# bytes型別無isnumberic方法
print(num2.isnumeric())  # True
print(num3.isnumeric())  # True
print(num4.isnumeric())  # True

# 三者不能判斷浮點數
num5='4.3'
print(num5.isdigit())
print(num5.isdecimal())
print(num5.isnumeric())

'''
總結:

    最常用的是isdigit,可以判斷bytes和unicode型別,這也是最常見的數字應用場景

    如果要判斷中文數字或羅馬數字,則需要用到isnumeric
'''

# is其他
print('===>')
name='alb123ert'
print(name.isalnum())  # 字串由字母或數字組成
print(name.isalpha())  # 字串只由字母組成
print(name.isidentifier())
print(name.islower())
print(name.isupper())
print(name.isspace())
print(name.istitle())
複製程式碼

三 列表

1. 列表型別基本介紹

在[]內用逗號分隔,可以存放n個任意型別的值,用於標識:儲存多個值的情況,比如一個人有多個愛好,定義格式示例:

students=['albert','james','kd',] 
# 或者students=list(['albert','james','kd',]) 
複製程式碼

列表可以儲存多個值,是有序的,是可變型別,不可以雜湊。

2. 列表型別常用的方法

(1) 新增元素

append方法 在列表最後追加元素

l1 = ['a', 'b', 'c', 'd', ]
l1.append('e')
print(l1)
print(l1.append('e'))
# 在隊尾追加,沒有返回值

# ['a', 'b', 'c', 'd', 'e']
# None
複製程式碼

insert方法 在列表中插入元素

l1 = ['a', 'b', 'c', 'd', ]
l1.insert(3,'x') # 3 指定插入索引3這個位置,就是“d”,這個位置,把‘d’ 頂到了後面
print(l1)

# insert可以指定插入的位置

# ['a', 'b', 'c', 'x', 'd']
複製程式碼

extend方法 在列表中同時插入多個元素,extend方法使用以及與append方法的區別 append是整體新增

l1 = [1, 2, 3, 4, 5, ]
l1.append([6, 7, 8, 9, ])
# l1.append(*[6, 7, 8, 9, ])  # 會報錯
print(l1)
l1.extend([6, 7, 8, 9])
print(l1)
複製程式碼

只能接收一個引數,如果出現打散的情況,還是會被識別成多個引數,因為程式執行執行是從左到右,從上倒下執行的,當出現時這個列表已經被打散了,因而,會被程式識別成被傳入了多個引數。

extend是逐個新增

l1 = [1, 2, 3, 4, 5, ]
l1.extend([6, 7, 8, 9])
print(l1)
l1.extend('abc')
print(l1)
l1.extend('a')  # 也是可迭代物件
print(l1)
# l1.extend(1)  # 報錯,不可迭代
print(l1)
複製程式碼

extend在執行新增的時候,被傳入的引數必須是可迭代物件,這樣通過迭代就解決了同時傳入多個引數的問題,如果你還不知道可迭代物件,放心,你很快就會知道的。

(2) 刪除元素

pop刪除,有返回值,預設刪除列表中最後一個,指定刪除索引值

l1 = [1, 2, 3, 4, 5, 6, ]
print(l1.pop())  # 這個是有返回值的,因為這是一個可迭代型別和我們前面的extend一類
print(l1)
print(l1.pop(2))  # 2指定是列表中的索引值
print(l1)
複製程式碼

remove 刪除 沒有返回值,沒有預設值,指定被刪除的元素

l1 = [1, 2, 3, 4, 5, 6, ]
print(l1.remove(2))  # 注意這個2 是真的2,不是索引值
# print(l1.remove())  # 報錯
print(l1)
複製程式碼

clear 刪除 保留列表名稱,清空裡面的值

l1 = ['a', 'b', 'c', 'd', 'e', 'b', 'c']
l1.clear()
print(l1)
複製程式碼

del 刪除 通用刪除 但是一般不用

l1 = [1, 2, 3, 4, 5, 6, ]
del l1[2]  # 按索引
print(l1)
l1 = [1, 2, 3, 4, 5, 6, ]
del l1  # 在記憶體中刪除l1 相當於沒有定義l1
# print(l1)  # 報錯
複製程式碼

(3) 更改元素

注意與insert插入的不同,都是以原來的為位置為參照,insert是擠開,本質是新增,而這裡是替換

l1 = [1, 2, 3, ]
l1[2] = 4
print(l1)
複製程式碼

(4) 查詢元素

按照索引或者指定列表中的元素查詢

l1 = ['a', 'b', 'c', 'd', 'e', 'b', 'c']
print(l1.index('a'))
print(l1.index('b',1,4))  # 兩個數字分別對應起始位置和結束位置
print(l1[0:5])  # 按照索引取值和字串的用法相同
print(l1[:5])
print(l1[0:5:2])
print(l1[:-1])
print(l1[:-2])
print(l1[5:1:-2])
複製程式碼

把列表分段查詢

l1 = ['a', 'b', 'c', 'd', 'e', 'b', 'c']
a = int(len(l1)/2)
print(l1[:a])  # 從中間位置開始,列出前面所有的元素
print(l1[a:])  # 從中間位置開始,列出後面所有的元素
複製程式碼

使用enumerate對列表列舉

l1 = ['a', 'b', 'c', 'd', 'e']
for i, x in enumerate(l1, 100):  # 100指定列舉開始的數字
    print(i, x)
複製程式碼

(5) 統計長度

print(len([1,2,3,4,]))
複製程式碼

(6) 統計元素個數

print(['a','b'].count('a'))
複製程式碼

(7) 排序 reverse 反序排序

l1 = ['a', 1, 'b', 'c', 'd', 'e', 'b', 'c']
l1.reverse()
print(l1)
複製程式碼

sort 按照ascii碼來進行排序

l1 = ['a', '1', 'b', 'c', 'd', 'e', 'b', 'A', 'Z', 'c']
l1.sort()
print(l1)
l1.sort(reverse=True)
print(l1)
複製程式碼

(7) 複製列表

l1 = ['a', '1', 'b', 'c', 'd', 'e', 'b', 'A', 'Z', 'c']
print(l1.copy())
複製程式碼

(8) Python中的賦值,淺拷貝與深拷貝區別 賦值 對於複製的操作,最簡單的就是賦值,指的是新建一個物件的引用,新建目標物件與原來的目標物件指向同一個記憶體地址,因而,始終保持一致。

list1 = [1, 2, 3, 4, 5, [6, 7, 8, ]]
list2 = list1
list1.append(9)
print(list1)
print(list2)
list1[5][0] = 10
print(list1)
print(list2)
list1[5] = 10
print(list1)
print(list2)
複製程式碼

淺拷貝 淺拷貝顧名思義就是拷貝的比較淺,我們可以把賦值認為是新建了一個物件的引用,把原來被物件記憶體空間的資料指向新的變數,這時同一塊記憶體空間指向兩個變數。淺拷貝與賦值不同,既然是拷貝,那麼就是要開闢一塊新的記憶體空間,複製的是原來被拷貝物件內多個元素物件的引用,有幾個元素物件就賦值幾個元素物件的引用。因此,被淺拷貝物件內的元素改變,會引起淺拷貝物件內元素的改變;被拷貝物件新增元素,拷貝物件不再新增元素(因為沒有一個新的引用);被拷貝物件刪除元素,拷貝物件也刪除元素(元素都已經刪了,雖然引用存在,但是並沒有什麼卵用)。

import copy


list1 = [1, 2, 3, 4, 5, [6, 7, 8, ]]
list2 = copy.copy(list1)
print(list1)
print(list2)

list1[5].append(9)
print(list1)
print(list2)

list1.append(6)
print(list1)
print(list2)

list1.pop()
print(list1)
print(list2)
複製程式碼

深拷貝 深拷貝其實與淺拷貝有本質的區別,它不會複製任何的引用,物件內的所有元素,子元素,孫子元素,重孫元素,曾孫元素的資料都是由複製而來。它的實現原理就是遞迴,只要任意元素內仍然有子元素,就會複製子元素的資料放到新的記憶體地址。既然這樣,在使用深拷貝後,被拷貝物件的改變,不會引起拷貝物件的任何改變。

import copy


list1 = [1, 2, 3, 4, 5, [6, 7, 8, ]]
list2 = copy.deepcopy(list1)
print(list1)
print(list2)

list1[5].append(9)
print(list1)
print(list2)

list1.append(6)
print(list1)
print(list2)

list1.pop()
print(list1)
print(list2)
複製程式碼

複製與深淺拷貝總結:

  • 賦值:新建一個原來物件記憶體地址的引用,不開闢新的記憶體空間;
  • 淺拷貝:新建多個原來物件內一級子元素記憶體地址的引用,開闢新的記憶體空間;
  • 深拷貝:複製原來物件內的所有N級子元素的資料,開闢新的記憶體空間。

四 元組

與列表型別相比,非常類似只不過[]換成(),作用:用於儲存多個值,對比列表來說,元組不可變(是可以當做字典的key的),不可更改,主要是用來讀。

age=(11,22,33,44,55)
# 本質age=tuple((11,22,33,44,55))
複製程式碼

元組可以儲存多個值,是有序的,是不可變型別,可以雜湊。元組常用的方法,請參考列表常用方法,需要注意的是,元組只能取值,而不能改變元組的值

五 字典

1. 字典型別基本介紹

字典用於存放一個人的資訊:姓名,性別,年齡,很明顯是多個值,既然是存多個值,我們完全可以基於剛剛學習的列表去存放,如下:

# 既然如此,我們我們為何還要用字典?
info=['albert','male',18]
# 定義列表的目的不單單是為了存,還要考慮取值,如果我想取出這個人的年齡,可以用
info[2]
# 但這是基於我們已經知道在第3個位置存放的是年齡的前提下,我們才知道索引2對應的是年齡,即:
#      # name, sex, age
info=['albert','male',18]
"""
而這完全只是一種假設,並沒有真正意義上規定第三個位置存放的是年齡,
於是我們需要尋求一種,即可以存放多個任意型別的值,又可以硬性規定值的對映關係的型別,
比如key=value,這就用到了字典
"""
複製程式碼

字典用於標識儲存多個值的情況,每個值都有唯一一個對應的key,可以更為方便高效地取值,字典的定義格式如下:

# 在{}內用逗號分隔,可以存放多個key:value的值,key一般是字串,value可以是任意型別
info={'name':'albert','age':18,'sex':18} 
# info=dict({'name':'albert','age':18,'sex':18})
複製程式碼

字典可以儲存多個值,是無序的,是可變型別,不可雜湊。

2. 字典型別常用的方法

(1) 增加元素

通過鍵值對的方式

l1 = {
    'name': 'albert',
    'age': 18,
    'gender': 'male'
}
l1['hobbies'] = "music"
print(l1)
複製程式碼

用fromkeys構造一個字典

"""
第一個引數迭代迴圈的字典的key,第二個參數列示value,
可以多個key迴圈對應這個value,也可以只有一個key,也可以沒有value
"""
a = l1.fromkeys(l1,'I am Albert') 
print(a)

b = dict.fromkeys('name')  # 必須有一個可迭代型別,作為字典的key
print(b)

b = dict.fromkeys('e')  # 也可以迭代
print(b)
# b = dict.fromkeys(1) #報錯 數字型別不可迭代

b = dict.fromkeys([1,2,3,])
print(b)
複製程式碼

(2) 刪除元素

del 通過字典的key刪除

l1 = {
    'name': 'albert',
    'age': 18,
    'gender': 'male'
}

del l1['name']
print(l1)
複製程式碼

pop 或者popitem刪除

l1 = {
    'name': 'albert',
    'age': 18,
    'gender': 'male'
}

res = l1.pop('name')  # 刪除指定key的value,並拿到一個返回值
print(res)
print(l1)

res2 = l1.popitem()  # 隨機返回並刪除字典中的一對鍵和值(一般刪除末尾對)。
# 如果字典已經為空,卻呼叫了此方法,就報出KeyError異常。
print(res2)
print(l1)
複製程式碼

(3) 更改元素

通過鍵值對的方式

l1 = {
    'name': 'albert',
    'age': 18,
    'gender': 'male','3':3,
}

l1['name'] = '馬一特'
print(l1)
複製程式碼

通過setdefault 或者update操作,兩者使用和區別如下: setdefault只新增不修改

d1 = {
    'name': 'albert',
    'age': 18,
}

d1.setdefault('name', 'Albert')
d1.setdefault('gender', 'male')
print(d1)
複製程式碼

update既新增也修改

d1 = {
    'name': 'albert',
    'age': 18,
}

d1.update({'name': 'Albert', 'gender': 'male'})  # 注意傳參方式的不同
print(d1)
複製程式碼

(4) 查詢元素

通過鍵值對查詢

l1 = {
    'name': 'albert',
    'age': 18,
    'gender': 'male'
}

a = l1['name']
print(a)
複製程式碼

通過get方法查詢

l1 = {
    'name': 'albert',
    'age': 18,
    'gender': 'male'
}

a = l1.get('hobbies')   # 找不到不報錯
print(a)
複製程式碼

通過enumerate 列舉

d1 = {
    'name': 'albert',
    'age': 18,
    'gender': 'male',
    '3':3,
}

for a in enumerate(d1):
    print(a)
複製程式碼

通過.keys(),.values(),.items()等方法

d1 = {
    'name': 'albert',
    'age': 18,
    'gender': 'male',
    '3':3,
}

a = d1.keys()
print(a)
print(list(a)[0])

a = d1.values()
print(a)
print(list(a)[0])

a = d1.items()
print(a)
print(list(a)[0])
複製程式碼

通過for迴圈遍歷

d1 = {
    'name': 'albert',
    'age': 18,
    'gender': 'male',
    '3':3,
}

for k,v in d1.items():
    print(k,v)
複製程式碼

(5) 成員運算與長度運算

參考列表的運算方法,成員運算的依據是字典的key,而不是value,長度運算都可以作為參考的依據

六 集合型別

花括號內,多個元素用逗號分割,用來儲存多個值,並且是無序的,那麼這多個值不能用來取值,但是我們可以使用它來進行去重和關係運算。

# 集合的元素遵循三個原則:
             1: 每個元素必須是不可變型別(可作為字典的key)
             2: 沒有重複的元素
             3: 無序
# 注意集合的目的是將不同的值存放到一起,不同的集合間用來做關係運算,無需糾結於集合中單個值
複製程式碼

集合型別可以存多個值,是無序的,是可變型別,不可以雜湊。
關係運算練習

有如下兩個集合,piano是報名鋼琴課程的學員名字集合,violin是報名小提琴課程的學員名字集合
&emsp;&emsp;piano={'albert','孫悟空','周星馳','朱茵','林志玲'}
&emsp;&emsp;violin={'豬八戒','郭德綱','林憶蓮''周星馳'}
&emsp;&emsp;1. 求出即報名鋼琴又報名小提琴課程的學員名字集合
&emsp;&emsp;2. 求出所有報名的學生名字集合
&emsp;&emsp;3. 求出只報名鋼琴課程的學員名字
&emsp;&emsp;4. 求出沒有同時這兩門課程的學員名字集合
複製程式碼

參考答案

# 求出即報名鋼琴又報名小提琴課程的學員名字集合
print(piano & violin)
# 求出所有報名的學生名字集合
print(piano | violin)
# 求出只報名鋼琴課程的學員名字
print(piano - violin)
# 求出沒有同時這兩門課程的學員名字集合
print(piano ^ violin)
複製程式碼

七 布林型別

計算機俗稱電腦,即我們編寫程式讓計算機執行時,應該是讓計算機無限接近人腦,或者說人腦能幹什麼,計算機就應該能幹什麼,人腦的主要作用是資料執行與邏輯運算,此處的布林型別就模擬人的邏輯執行,即判斷一個條件成立時,用True標識,不成立則用False標識。

#布林值,一個True一個False
>>> a=3
>>> b=5
>>> a > b #不成立就是False,即假
False
>>> a < b #成立就是True, 即真
True
# 接下來就可以根據條件結果來幹不同的事情了:
if a > b:
   print(a is bigger than b )
else:
   print(a is smaller than b )
# 上面是虛擬碼,但意味著,計算機已經可以像人腦一樣根據判斷結果不同,來執行不同的動作。
複製程式碼

布林型別的重點知識

#所有資料型別都自帶布林值
1None0,空(空字串,空列表,空字典等)三種情況下布林值為False
2、其餘均為真
複製程式碼

可變型別與不可變型別(重點)

# 1.可變型別:在id不變的情況下,value可以變,則稱為可變型別,如列表,字典
# 2. 不可變型別:value一旦改變,id也改變,則稱為不可變型別(id變,意味著建立了新的記憶體空間)
複製程式碼

八 collections容器資料型別

1. namedtuple 命名元組

from collections import namedtuple
# 建立一個命名元組物件
point = namedtuple('p', ['x', 'y'])  # p代表名稱,"x"和"y"為內容
p = point(1, 2)
print(p)
print(p.x)  # 1
print(p.y)  # 2
複製程式碼

2. deque 超級列表

from collections import deque
# 類似列表(list)的容器,實現了在兩端快速新增(append)和彈出(pop)
d = deque('abcd')
for i in d:
    print(i)
print(d[0])
print(d[1])
d.append('e')  # 從右邊加入
print(d)
d.appendleft('x')  # 從左邊加入
print(d)
d.pop()  # 從右側彈出
print(d)
d.popleft()  # 從左側彈出
print(d)
deque(reversed(d))  # 反轉順序
print(d)
# d = list(d)  # 轉化成list
# d = list(reversed(d))
# print(d)
d.extend('xyz')  # 從右側新增
print(d)
d.extendleft('nba')  # 從左側新增
print(d)
d.rotate(1)  # 把最右邊的元素挪到最左邊
print(d)
d.rotate(-1)  # 把最左邊的元素挪到最右邊
print(d)
d.clear()  # 清空
# d.pop()  # 報錯
複製程式碼

3. ChainMap 鏈對映

from collections import ChainMap
"""
一個 ChainMap 類是為了將多個對映快速的連結到一起,這樣它們就可以作為一個單元處理。
它通常比建立一個新字典和多次呼叫 update() 要快很多。
這個類可以用於模擬巢狀作用域,並且在模版化的時候比較有用。
"""
# 鏈對映的用法
dict1 = {'name': 'Albert', 'age': 18}
dict2 = {'weight': 65, 'height': 180}
res = list(ChainMap(dict1, dict2))
print(res)
複製程式碼

4. Counter 計數字典

from collections import Counter
# 計數
cnt = Counter()
for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
    cnt[word] += 1
print(cnt)
# Counter({'blue': 3, 'red': 2, 'green': 1})
# 數學運算
c = Counter(a=3, b=1)
d = Counter(a=1, b=2)
print(c + d)  # 相同的部分相加
# Counter({'a': 4, 'b': 3})
print(c - d)  # 相同的部分相減
# Counter({'a': 2})
print(c & d)  # 相同的部分取最小
# Counter({'a': 1, 'b': 1})
print(c | d)  # 相同的部分取最大
# Counter({'a': 3, 'b': 2})
複製程式碼

Collections容器型別一共有9種,除了上面介紹的4種之外還有OrderedDict,defaultdict,UserDict,UserList,UserString,他們的用法不是完全相同,但是使用起來並不複雜,更多Collections容器型別資料結構詳見官方文件:Collections容器資料型別

相關文章