Python 數(shù)據(jù)類型

變量

可以說(shuō)python只有名字沒(méi)有變量伦籍,不需要定義類型,你賦值啥他就啥類型(所以定義變量時(shí)就得賦值腮出,有int帖鸦、float、str胚嘲、bool)作儿,甚至可以賦值其他類型,例如:

a=1
a='a'

那么a就從int變成char馋劈,這是可以的攻锰,還有就是比如:

>>> 5+3
8    #兩個(gè)int晾嘶,按正常計(jì)算
>>> '5+3'
'5+3'    #整個(gè)是str,所以不變
>>> '5'+'3'
'53'    #兩個(gè)str娶吞,結(jié)果拼在一起

命名時(shí)可以包括字母垒迂、數(shù)字和下劃線,但不能以數(shù)字開(kāi)頭妒蛇,且大小寫敏感
注:
python作為一門動(dòng)態(tài)語(yǔ)言不需要指明變量類型机断,但這樣也就少了編譯時(shí)檢查錯(cuò)誤的環(huán)境(無(wú)法做類型檢查),只有在運(yùn)行時(shí)才能知道是否存在錯(cuò)誤

變量實(shí)質(zhì)

python當(dāng)中的變量實(shí)際就只是一個(gè)指針绣夺,指向?qū)?yīng)數(shù)據(jù)的地址吏奸,因此python的變量可以隨意修改指向,舉例:

a = 1
print(id(a), id(1))
a = 2
print(id(a), id(1), id(2))
# 會(huì)發(fā)現(xiàn)a只是將指針指向了2

# 1892936144 1892936144
# 1892936176 1892936144 1892936176

在python內(nèi)部有個(gè)intern機(jī)制:將一定范圍內(nèi)的數(shù)或者短的字符串提前載入內(nèi)存陶耍,建立全局唯一的對(duì)象奋蔚,下次再使用時(shí)則直接指向他

e記法

python里計(jì)數(shù)可以用科學(xué)計(jì)數(shù)法,例如0.0002就可以是2e-4烈钞,500000可以是5e5泊碑,但是e記法的數(shù)一定是浮點(diǎn)數(shù),所以5e5 = 5.0e5 = 500000.0

bool類型

True就是1棵磷,False就是0(記住都是首字母大寫)蛾狗,所以可以True * False(1*0=0),類似這樣仪媒,但是不能True / False(0不能做分母)沉桌,當(dāng)然這些做法可以,但是不推薦
注:
所有值為0的:0算吩、0+0j留凭、0.0,空字符串''偎巢、空列表[]蔼夜、空元組()、空字典{}压昼、空集合set()None都是False求冷,其他都是True

強(qiáng)制轉(zhuǎn)型

python支持,例如:a = int(1.666)窍霞,結(jié)果a為1匠题,其中float轉(zhuǎn)int是將小數(shù)點(diǎn)的數(shù)后直接砍掉。還有其他的強(qiáng)轉(zhuǎn)如下:

#類型轉(zhuǎn)換
float()  #轉(zhuǎn)成float
str()  #轉(zhuǎn)成str但金,如果是幾種類型混合韭山,其會(huì)用連接符表示,比如:`a = str(ab1)`,就會(huì)變成`'ab+1'`
#進(jìn)制轉(zhuǎn)換
bin()  #轉(zhuǎn)二進(jìn)制
oct()  #轉(zhuǎn)八進(jìn)制
int()  #轉(zhuǎn)十進(jìn)制
hex()  #轉(zhuǎn)十六進(jìn)制

對(duì)上面強(qiáng)轉(zhuǎn)舉例:

>>> bin(21)
'0b10101'
>>> type(bin(21))
<class 'str'>
>>> oct(10)
'0o12'
>>> hex(10000)
'0x2710'

可以看出除了十進(jìn)制的钱磅,其他幾種進(jìn)制強(qiáng)轉(zhuǎn)都是前綴加數(shù)字部分梦裂,類型也都是字符串型,所以如果想要只取數(shù)字部分就可以通過(guò)replace()替換掉前綴
注:
強(qiáng)轉(zhuǎn)時(shí)盖淡,不要有以其命名的變量年柠,例如:

>>> str = 1
>>> str(2)
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    str(2)
TypeError: 'int' object is not callable

可以看出報(bào)錯(cuò)了,說(shuō)str是int類型禁舷,無(wú)法被調(diào)用彪杉,說(shuō)白了就是str已經(jīng)被當(dāng)成前面的變量1了,所以現(xiàn)在只是個(gè)數(shù)字而已(實(shí)際上現(xiàn)在獲取的str是全局空間的牵咙,而不是內(nèi)置空間的str)

python中負(fù)數(shù)的二進(jìn)制展示問(wèn)題:
對(duì)于十進(jìn)制數(shù)據(jù)派近,通過(guò)bin轉(zhuǎn)成二進(jìn)制時(shí),是直接將其轉(zhuǎn)成正數(shù)的二進(jìn)制加上一個(gè)負(fù)號(hào)洁桌;而對(duì)于十六進(jìn)制通過(guò)bin轉(zhuǎn)二進(jìn)制時(shí)渴丸,才是返回真正的二進(jìn)制表示,舉例:

>>> bin(-100)
'-0b1100100'
>>> bin(-100 & 0xffffffff)
'0b11111111111111111111111110011100'

參考:https://www.runoob.com/w3cnote/python-negative-storage.html

"""長(zhǎng)字符串"""

像特別長(zhǎng)的字符串甚至有換行另凌,好幾行的那種谱轨,光用'或者"引起來(lái)是不行的,此時(shí)可以用頭尾各3個(gè)"包起來(lái)實(shí)現(xiàn)吠谢,舉例:

"""
這是
一個(gè)
多行
長(zhǎng)字符串
"""

字符串(str)

基本使用

用單引號(hào)或雙引號(hào)包起來(lái)的字符組合土童,但要注意不能單引號(hào)/雙引號(hào)自己給自己嵌套使用,比如下面的用法是不正確的:

'在'單引號(hào)'里面嵌套單引號(hào)' 
"在"雙引號(hào)"里面嵌套雙引號(hào)"

所以如果要在字符串中表示單引號(hào)/雙引號(hào)工坊,可以混合著使用献汗,或者使用轉(zhuǎn)義字符,例如下面的方式:

'"雙引號(hào)被單引號(hào)包著"'
"'單引號(hào)被雙引號(hào)包著'"
'使用轉(zhuǎn)義的單引號(hào):\''

其可以幾個(gè)字符用+連起來(lái)(得都是字符串類型)王污,也可以*起來(lái)罢吃,舉例:

>>> 'aaa'+ str(2)    #+起來(lái)時(shí)要求同種類型
'aaa2'
>>> 'aaa'*2    #*起來(lái)時(shí)不要求為同種類型
'aaaaaa'
開(kāi)頭加r

假如給變量賦值如下:str='c:\now',那么在print里輸出時(shí)昭齐,\n會(huì)被轉(zhuǎn)義尿招,為了避免這種情況,此時(shí)我們可以用\\替換\阱驾,這是解決只有少數(shù)地方會(huì)被轉(zhuǎn)義的情況就谜。
但是如果是多路徑比如:'c:\now\abc\ttt'時(shí),每個(gè)地方都用\\來(lái)替換會(huì)很麻煩里覆,所以此時(shí)就可以在字符串前面加個(gè)r丧荐,代表原始字符串,例如:str=r'c:\now\abc\ttt'租谈,則str就會(huì)自動(dòng)變成c:\\now\\abc\\ttt,用print輸出時(shí)就是正常的c:\now\abc\ttt

開(kāi)頭加u

一般在內(nèi)容為中文時(shí)用,代表內(nèi)容用utf-8編碼的字符串

開(kāi)頭加b

代表字節(jié)類型割去,即byte類型窟却,字節(jié)流通過(guò)decode(編碼)來(lái)解碼成字符串,反過(guò)來(lái)字符串通過(guò)encode(編碼)來(lái)編碼成字節(jié)類型呻逆,舉例:

>>> type(b'abc')  //字節(jié)類型
<class 'bytes'>
>>> type(u'abc')  //字符串類型
<class 'str'>
>>> type(b'abc'.decode('utf-8'))  //字節(jié)流解碼成字符串
<class 'str'>
>>> type(u'abc'.encode('utf-8'))  //字符串編碼成字節(jié)流
<class 'bytes'>
分片

可以用分片方法截取字符串的一部分夸赫,例如str1='abcde'微峰,只取其中abc就可以:str1[:3]田盈,取'cbce'就可以:str1='c'+str1[1:3]+'e'

查詢索引

字符串其實(shí)可以看作是一個(gè)特殊的數(shù)組隘击,其每個(gè)字符按順序排放缀程,所以可以像查數(shù)組那樣墓贿,例如上面的str1曙砂,如果:str1[1]就會(huì)輸出'b'扳躬,即第二個(gè)字符

通用方法

字符串能使用的方法特別多点楼,像count()計(jì)數(shù)辐董、index()索引(find方法也可以索引悴品,使用跟index一樣,但index找不到會(huì)報(bào)錯(cuò)简烘,find會(huì)返回-1苔严,還有像rfind方法,是從右邊開(kāi)始查孤澎,很多r開(kāi)頭的都是從右邊開(kāi)始的意思)啥的都能用届氢,參照列表,還有一些常用方法如下:

把第一個(gè)字母改為大寫

str1.capitalize()

把所有字母改為大寫

str1.upper()

將字符串所有內(nèi)容改為小寫

str1.casefold()

將字符串居中

例如我要一個(gè)長(zhǎng)度10的字符串覆旭,然后原來(lái)的字符串內(nèi)容在里面就可以:str1.center(10)退子,結(jié)果就是' abcde ';如果要居左就用ljust姐扮,舉例:

>>> "abc".ljust(10) #居左
'abc       '
>>> "abc".rjust(10) #居右
'       abc'
指定編碼

str1.encode(encoding='utf-8',error='strict')
表示指定為utf-8編碼絮供,error參數(shù)代表設(shè)置不同錯(cuò)誤的處理方案,默認(rèn)為strict茶敏,此時(shí)當(dāng)編碼不符是會(huì)報(bào)錯(cuò)壤靶,如果要設(shè)置寬松點(diǎn)的情況可以用ignore,此時(shí)會(huì)忽略這個(gè)錯(cuò)誤

判斷字符串是否以某子字符串結(jié)束

endswith(sub[,start[,end]])
例如判斷上面str1:str1.endswith('e')惊搏,因?yàn)槭且?e'結(jié)尾贮乳,所以返回True(判斷'de'、'cde'啥的也是對(duì)的)恬惯,如果判斷是否以某字符串開(kāi)頭用startswith()

把'\t'變成空格
>>> str2='a\tbcd\tc'
>>> str2.expandtabs()
'a(7個(gè)空格)bcd(5個(gè)空格)c'

(因?yàn)槿绻椒ɡ锊惶钊霐?shù)字向拆,默認(rèn)為8個(gè)空格,而tab又是從這個(gè)字符串頭開(kāi)始數(shù)加上空格共8位酪耳,所以a后面加7個(gè)空格浓恳,bcd加5個(gè))

判斷是否為只有字母的非空字符串

str1.isalpha()
結(jié)果返回True或False

判斷是否只有字母或數(shù)字(可以都有)的非空字符串

str1.isalnum()

判斷是否只有數(shù)字的非空字符串

str1.isnumertic()刹缝,還有isdigit()都是判斷數(shù)字,但是numertic就算漢字?jǐn)?shù)字比如四也是True颈将,而digit是False梢夯,還有一個(gè)是isdecimal()
三者區(qū)別參考:
http://www.cnblogs.com/jebeljebel/p/4006433.html

判斷字符串是否是標(biāo)題,即字母都以大寫開(kāi)始晴圾,其余位均小寫
>>> str1='Abc'
>>> str2='AbC'
>>> str1.istitle() 
True
>>> str2.istitle() #(要把字符串變標(biāo)題形式就用title())
False
>>> 
以sub做分隔符插入到字符

str1.join()颂砸,舉例:

>>> str1='abc'
>>> str1.join('123')
'1abc2abc3'
替換字符串

str1.replace(),舉例:

>>> str1='abcabcabc'
>>> str1.replace('b','d',2)
'adcadcabc'

對(duì)于其參數(shù)死姚,第一個(gè)是要替換的字符人乓,第二個(gè)是替換成的,第三個(gè)是最多替換幾個(gè)(第三個(gè)參數(shù)可選都毒,默認(rèn)全部替換)

分割字符串

str1.split()色罚,舉例:

>>> str1='i love   you'  #第二個(gè)中間有3個(gè)空格
>>> str1.split()  #按1到多個(gè)空格分割
['i', 'love', 'you']
>>> str1.split(' ')  #按單個(gè)空格分割
['i', 'love', '', '', 'you']
>>> str1.split('i')
['', ' love   you']

括號(hào)是選擇按什么字符串分割,默認(rèn)是空格(1到多個(gè))温鸽,比如括號(hào)里是'i'保屯,結(jié)果就是['',' love you'],'i'被切了涤垫,左邊是空字符串
注:
split還有第二個(gè)參數(shù)姑尺,代表從左到右對(duì)前幾個(gè)指定字符進(jìn)行分割,舉例:

>>> a = "x.y.z.k.q"
>>> a.split('.')
# 默認(rèn)對(duì)所有.都分割
['x', 'y', 'z', 'k', 'q']
>>> a.split('.', 1)
# 只對(duì)從左到右第一個(gè)點(diǎn)分割
['x', 'y.z.k.q']
>>> a.split('.', 2)
# 只對(duì)從左到右第二個(gè)點(diǎn)分割
['x', 'y', 'z.k.q']

同理從右到左可以用rsplit方法實(shí)現(xiàn)

按行切割

split會(huì)對(duì)一到多個(gè)空格蝠猬、縮進(jìn)切蟋,以及換行等都進(jìn)行切割,但splitlines只會(huì)根據(jù)行來(lái)切割榆芦,舉例:

>>> a = """sda s
dsadas
gdfgd"""
>>> 
>>> a.split()
# 可以看到空格和行的都被切割了
['sda', 's', 'dsadas', 'gdfgd']
>>> a.splitlines()
# 可以看到僅按行切割
['sda s', 'dsadas', 'gdfgd']
刪除字符串前面或后面的所有某一個(gè)字符串

str1.strip()柄粹,舉例:

>>> str1='abacaa'
>>> str1.strip('a')
'bac'

只會(huì)刪除前面和后面,中間不管匆绣,括號(hào)里沒(méi)東西默認(rèn)刪空格驻右,如果只要?jiǎng)h除左邊的某些字符就用:lstrip(),右邊就用rstrip()崎淳,可以疊加使用堪夭,比如:

>>> str1='abacaa'
>>> str1.strip('a').rstrip('c')
'ba'
翻轉(zhuǎn)字符串大小寫

str1.swapcase(),舉例:

>>> str1='aBc'
>>> str1.swapcase()
'AbC'
翻轉(zhuǎn)字符串內(nèi)容

常用的方法有分片拣凹、列表翻轉(zhuǎn)后轉(zhuǎn)字符串森爽、循環(huán),舉例:

#分片
>>> a = 'abcde'
>>> a[::-1]
'edcba'
#列表翻轉(zhuǎn)字符串
>>> b = list(reversed(a))
>>> "".join(b)
'edcba'
#for循環(huán)就不舉例了嚣镜,就列表翻轉(zhuǎn)然后一一遍歷相加
更多字符串方法參考

http://bbs.fishc.com/thread-38992-1-1.html

列表(list)

創(chuàng)建一個(gè)空列表:

empty=[]

不像數(shù)組必須都得存放同一種數(shù)據(jù)爬迟,列表里面可以放各種數(shù)據(jù)類型,例如:

user = [123 ,'abc' ,'用戶1' ,[1,2,3,4]]

其中列表內(nèi)每個(gè)對(duì)應(yīng)下標(biāo)為從0開(kāi)始菊匿,但比較特殊的是比如上面的user[3]是一個(gè)列表:[1,2,3,4]付呕,所以如果要定位到4的下標(biāo)就用user[3][3]计福,即以二維數(shù)組的方式

添加元素
append()方法

例如對(duì)上面的user:user.append('新用戶'),這個(gè)就會(huì)被加到列表的最后一個(gè)徽职,因?yàn)樵谧詈笠晃话羲眩钥梢酝ㄟ^(guò)user[-1]查看。要注意append只能加一個(gè)參數(shù)

extend()方法

想要加多個(gè)參數(shù)時(shí)可以用extend()方法活箕,但是注意extend()也只能傳一個(gè)參數(shù),不過(guò)他可以傳一個(gè)列表參數(shù)(其實(shí)是迭代器可款,但是可以先當(dāng)成是一個(gè)列表)育韩,其原理就是把傳過(guò)去的列表內(nèi)容分別加到后面,從而傳進(jìn)多個(gè)參數(shù)闺鲸,例如對(duì)上面的user: user.extend(['a','b'])筋讨,結(jié)果就添加了'a'和'b'進(jìn)去
注意要以列表形式傳多個(gè)參數(shù),如果直接傳多個(gè)參數(shù)摸恍,比如extend('a','b')就會(huì)報(bào)錯(cuò)
注:
  append()也能傳列表悉罕,但和extend()不同,extend是默認(rèn)傳入列表立镶,所以會(huì)依次把列表里的參數(shù)傳進(jìn)去壁袄;而append傳列表時(shí)就是單純的傳一個(gè)列表進(jìn)去,比如前面通過(guò)兩種方法傳['a','b']媚媒,在extend里傳入的是'a'和'b'嗜逻,在append里傳入的是['a','b']

insert()方法

想要傳到自己想要的位置時(shí)可以用insert()方法,例如想傳字符串'c'到上面user列表的第二個(gè)位置:user.insert(1,'c')缭召,其編號(hào)也是從0開(kāi)始的
注:
當(dāng)對(duì)列表使用+或者+=(兩種方法實(shí)質(zhì)是有區(qū)別的)時(shí)也可以添加元素栈顷,+操作算是新建一個(gè)新的列表并添加元素,而不是對(duì)原來(lái)列表添加元素嵌巷,所以原來(lái)的列表并不會(huì)發(fā)生改變萄凤,而+=是在原來(lái)的列表里添加元素,所以效率上比+要高些搪哪,舉例:

>>> a = [1,2,3]
>>> b = a + [4] #新建一個(gè)列表b存放a和[4]相加的列表
>>> b
[1, 2, 3, 4]
>>> a #a并沒(méi)有發(fā)生改變
[1, 2, 3]
>>> a = [1,2,3]
>>> a += [4]
>>> a
[1, 2, 3, 4]

注2:
幾種添加元素效率比對(duì)(一般情況下):+<insert<extend<append<+=

調(diào)換元素

拿上面user對(duì)調(diào)第一第二個(gè)元素舉例:

temp=user[0]
user[0]=user[1]
user[1]=temp

當(dāng)然python里還可以支持更精簡(jiǎn)的寫法:

user[0], user[1] = user[1], user[0]

結(jié)果和前面是一樣的靡努,還有就是可以用列表分片方法來(lái)替換元素,參考下面的列表分片

刪除元素
remove()方法

按變量名刪除噩死,例如:user.remove('abc')颤难,如果有同名的變量就只刪除第一個(gè),如果想把某個(gè)同名元素全部刪除已维,可以循環(huán)判斷當(dāng)存在某個(gè)元素時(shí)則刪除該元素行嗤,舉例:

while "abc" in user:
    li_safe_content.remove("abc")
del函數(shù)

按其下標(biāo)位置刪除,例如刪除user的第一個(gè)變量:del user[1]垛耳,del后面加變量名甚至可以刪除整個(gè)變量栅屏,例如:del user就會(huì)把整個(gè)user列表刪了

pop()方法

其會(huì)彈出一個(gè)元素(和刪除有點(diǎn)區(qū)別飘千,其在刪除元素的基礎(chǔ)上,還會(huì)將該元素作為返回值輸出)栈雳,例如:user.pop(1)护奈,就會(huì)刪除列表的第2個(gè)元素(如果括號(hào)里沒(méi)數(shù)字就默認(rèn)彈出最后一個(gè)),并輸出哥纫,我們可以把這個(gè)給賦值存儲(chǔ)以備后面要用霉旗,例如:temp = user.pop(),此時(shí)刪除最后一個(gè)值并賦值給temp

刪除重復(fù)元素

可以使用numpy模塊下的unique()方法蛀骇,然后再用list()方法轉(zhuǎn)成列表厌秒,也可以用set()方法轉(zhuǎn)成集合后再轉(zhuǎn)回來(lái),舉例:

>>> a = [1,2,3,1,2,1]
>>> list(set(a))
[1, 2, 3]
列表分片

可以截取列表的一部分擅憔,比如:user[1:3]說(shuō)明從下標(biāo)為1的截取到下標(biāo)為3的(不包括3)鸵闪,還可以user[:3],說(shuō)明從第1個(gè)到下標(biāo)為3的(不包括3)暑诸,user[:]說(shuō)明截全部蚌讼,user[:-2]說(shuō)明截取去掉最后兩個(gè)數(shù)據(jù)后的列表;其還有第三個(gè)可選參數(shù)个榕,意思是變化量篡石,舉例:

>>> d = [1,3,4,5,8]
>>> d[:4:2]     #截取從第一個(gè)到第4個(gè),每次跨兩步(隔一個(gè))取
[1, 4]
>>> d[::-1]     #截取整個(gè)列表西采,變化量為-1夏志,即取倒過(guò)來(lái)的列表
[8, 5, 4, 3, 1]

切片還可以迭代(連續(xù))切片,舉例:

>>> d = [1,3,4,5,8]
>>> d[1:4][1:]      #先切出2到4個(gè)([3,4,5])苛让,然后再切2到后面的所有
[4, 5]
>>> b = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
>>> b[1:][1] [3]      #先切出2到后面([[5, 6, 7, 8], [9, 10, 11, 12]])沟蔑,然后取第2個(gè)([9, 10, 11, 12])的第4個(gè)
12 

上面說(shuō)的通過(guò)列表替換元素方式如下:

>>> a = [1,2,3,4,5]
>>> a[1:3] = [6,6,6,6,6]  #把2、3位替換成5個(gè)6
>>> a
[1, 6, 6, 6, 6, 6, 4, 5]

注:
分片一般用來(lái)截取一個(gè)新的列表狱杰,例如:temp = user[1:3]瘦材,此時(shí)temp就是一個(gè)新列表了,這里要注意下:temp1=user[:]temp2=user雖然看起來(lái)都是復(fù)制整個(gè)user仿畸,但實(shí)際上不一樣食棕,temp1應(yīng)該更像是截取,所以u(píng)ser無(wú)論怎么變化错沽,跟temp1都無(wú)關(guān)簿晓,而temp2更像是直接指向user,所以是和user同步的千埃,user做了什么操作憔儿,temp2也會(huì)跟著改,這也是為什么需要列表分片來(lái)復(fù)制列表的原因之一

邏輯操作

兩個(gè)列表比較大小放可,只比較第一個(gè)元素谒臼,如果第一個(gè)一樣再比第二個(gè)...朝刊;兩個(gè)列表相加就是后一個(gè)的變量加到前一個(gè)的后面;列表還可以和一個(gè)數(shù)相乘蜈缤,就是把列表里的內(nèi)容重復(fù)幾次拾氓,例如:

>>> a=[1,2,3]
>>> a*2
[1,2,3,1,2,3]

注:
  在數(shù)據(jù)分析模塊里有數(shù)組概念,其邏輯操作則和C當(dāng)中數(shù)組一樣底哥,兩個(gè)數(shù)組相加就把同一位置的值相加咙鞍,相乘除就把所有值都乘除一定大小

判斷是否在列表

in或者not in(成員關(guān)系操作符),例如a[]里面有1趾徽,所以:1 in a 就會(huì)是True奶陈,但只能判斷第一層,假如a列表為a[2,3,[1,2,3]] 附较,那么判斷結(jié)果就為False,假如這時(shí)還想判斷是否存在1潦俺,可以用:1 in a[2]拒课,因?yàn)樵诘?個(gè)元素里所以用a[2]

計(jì)算參數(shù)個(gè)數(shù)

count()方法,括號(hào)里輸入?yún)?shù)名事示,例如:

>>> a=[1,2,3,1,2]
>>> a.count(1)
2

既然count()可以計(jì)算列表里某個(gè)元素的數(shù)量早像,那么就可以通過(guò)將其和集合結(jié)合起來(lái),獲取列表每個(gè)數(shù)據(jù)的數(shù)量肖爵,舉例:

li = [3, 9, 3, 2, 5, 6, 7, 3, 2, 3, 3, 3]
dict1 = {}
#用字典來(lái)存儲(chǔ)結(jié)果
for i in set(li):
    dict1[i] = li.count(i)
print(dict1)

結(jié)果:
{2: 2, 3: 6, 5: 1, 6: 1, 7: 1, 9: 1}
索引參數(shù)位置

index()方法卢鹦,但如果只輸入要查找的變量名就只會(huì)告訴你第一個(gè)該參數(shù)的位置,例如對(duì)上面的a:a.index(2)輸出就是1劝堪,所以可以在index里再加2個(gè)參數(shù)確定索引的開(kāi)頭和結(jié)尾冀自,例如在第三個(gè)到第五個(gè)之間查2:a.index(2,2,4)

合并列表

在字符串中有split()來(lái)把字符串分割成列表,所以也有join()把列表合并成字符串秒啦,相當(dāng)于split()的逆方法熬粗,比如:

>>> a = '-' #中間用a的值隔開(kāi)
>>> b = a.join(['sad', '2', 'gds'])
>>> b
'sad-2-gds'
>>> b.split('-')
['sad', '2', 'gds']
翻轉(zhuǎn)列表

reverse()方法,舉例:

>>> a=[1,2,3]
>>> a.reverse()
[3,2,1]
列表排序

sort()方法余境,如果不輸入?yún)?shù)則默認(rèn)從小到大排序(列表內(nèi)容必須為可對(duì)比的類型驻呐,例如列表里同時(shí)存在數(shù)字和字母就會(huì)報(bào)錯(cuò)),舉例:

>>> a=[2,4,3]
>>> a.sort()
[2,3,4]

其實(shí)sort有3個(gè)參數(shù)芳来,即sort(function,key,reverse=False)含末,function是自己指定的算法,key代表和算法搭配的關(guān)鍵字即舌,第三個(gè)代表是否倒序佣盒,默認(rèn)為False代表不倒序,如果要倒序就改成True顽聂,例如對(duì)b=['s','ac','gdsa']進(jìn)行按字符串長(zhǎng)度的倒序排序則:b.sort(key=len,reverse=True)
注:
列表翻轉(zhuǎn)和排序只會(huì)對(duì)當(dāng)前列表進(jìn)行操作沼撕,且沒(méi)有返回值宋雏,所以如果想把列表翻轉(zhuǎn)/排序后賦值給另一個(gè)列表要分兩步進(jìn)行,看下面代碼:

>>> a = [2,3,7,5,1]
>>> b = a.sort()
>>> b
#可以看出b是指向空的务豺,并沒(méi)有把a(bǔ)排序后返回傳給b
>>> a
[1, 2, 3, 5, 7]
#但是可以看出a已經(jīng)排好序了
>>> a.reverse()
>>> b = a
>>> b
[7, 5, 3, 2, 1]
#可以看出如果要翻轉(zhuǎn)/排序后賦值磨总,分兩步進(jìn)行就能成功
打亂列表順序

參考random模塊的shuffle()方法,把列表作為參數(shù)傳入即可笼沥,舉例:

>>> import random
>>> a
[1, 2, 5, 3, 7]
>>> random.shuffle(a)
>>> a
[5, 3, 1, 7, 2]

元組(tuple)

和列表非常像蚪燕,區(qū)別是其內(nèi)容不可修改,所以像排序啥的操作基本都沒(méi)有

特點(diǎn)
  • 可迭代
  • 不可變
  • 可拆包

注:
元組的不可變性是指存放的內(nèi)容地址不可變奔浅,并不是內(nèi)容不可變馆纳,舉例:

content = [1,2,3]
a = (content,4)
print(a)
content.pop()
print(a)

# ([1, 2, 3], 4)
# ([1, 2], 4)

可以看到元組內(nèi)部存放的列表內(nèi)容是可以改變的,但列表的內(nèi)容改變汹桦,列表的內(nèi)存地址并沒(méi)有一起改鲁驶,所以是允許的

與list比較
  • 由于不可變,所以其會(huì)作為常量舞骆,在編譯時(shí)就能夠確定內(nèi)容钥弯,因此性能更好
  • 由于不可變,因此可以進(jìn)行哈希運(yùn)算(要求元組內(nèi)部的數(shù)據(jù)也是可哈希類型的督禽,例如元組內(nèi)部存放了列表脆霎,那么就不能進(jìn)行哈希運(yùn)算了),也就可以存放到集合或者字典的key當(dāng)中
  • 線程安全
定義元組

定義方法是用小括號(hào)狈惫,例如:a=(1,2,3,4,5)睛蛛,創(chuàng)建一個(gè)空元組:a=(),但是元組的標(biāo)志性符號(hào)是逗號(hào)不是小括號(hào)胧谈,例如定義:a=(1)忆肾,用type函數(shù)會(huì)發(fā)現(xiàn)a是int型,而定義:a=1,2,3菱肖,會(huì)發(fā)現(xiàn)a是元組难菌,所以說(shuō)逗號(hào)才是元組的標(biāo)志,像前面如果想創(chuàng)建只有一個(gè)元素的元組就得后面加個(gè)逗號(hào)蔑滓,例如:a=(1,)(不用括號(hào)也可以)

查詢?cè)M

和列表查詢一樣郊酒,例如查第二個(gè):a[1](就創(chuàng)建時(shí)候用小括號(hào))
注:
  除了定義、刪除的語(yǔ)法還有不可修改的規(guī)定和列表不同外键袱,其他的使用方法和列表幾乎相同燎窘,如分片:b=a[1:];還有像count()(計(jì)算出現(xiàn)次數(shù))蹄咖、index()方法(索引)褐健、innot in和一些邏輯操作符都可以用,參照上面列表用法

更新元組

雖然說(shuō)元組不能修改蚜迅,但是我們可以更新他舵匾,比如在前面的a的第二個(gè)位置插入6,可以這樣:a=a[:1]+(6,)+a[1:](這里括號(hào)和逗號(hào)都要在)谁不,這時(shí)候就更新元組了坐梯,這里不是改變,因?yàn)閍被重新賦值了刹帕,已經(jīng)不是原來(lái)的他了(用id(b)可以發(fā)現(xiàn)地址已變)

刪除元組

一般刪除元組里的內(nèi)容就用分片截取就好了吵血,跟上面的更新差不多,如果要?jiǎng)h除整個(gè)元組就用del函數(shù)偷溺,例如:del a
注:
  上面知道元組的標(biāo)志是逗號(hào)蹋辅,所以(8)是代表整數(shù)8,(8,)代表元組8,挫掏,所以如果用8與上面兩個(gè)分別相乘將會(huì)是不同的結(jié)果:

>>> (8)*8
64
>>> (8,)*8
(8,8,8,8,8,8,8,8)

注2:
  列表侦另、元組可以同時(shí)給多個(gè)變量同時(shí)賦值,例如:

>>> x = [1,2,3,4,5]
>>> a,b,c,d,e =x
>>> a
1
>>> a,b,c,d,e
(1, 2, 3, 4, 5)
#可以看出此時(shí)a,b,c,d,e就變成對(duì)應(yīng)的1,2,3,4,5了

前提是賦值變量數(shù)和列表/元組數(shù)值量相同

拆包
a = [1,2,3,4]
b, *c, d = a
print(b, c, d)

# 1 [2, 3] 4

集合(set)

如同字面意思尉共,跟數(shù)學(xué)的集合一樣褒傅,里面的數(shù)據(jù)都是唯一的(最主要意義,所以一般用來(lái)去除重復(fù)內(nèi)容)爸邢,而且是無(wú)序的

定義
  1. 直接用{}定義:舉例:num1 = {1,2,3,3,4,2,1} ,因?yàn)橹滴ㄒ荒美ⅲ詎um1為{1, 2, 3, 4}
  2. set()函數(shù):舉例:set1 = set([1,2,3,3,2,1])杠河,括號(hào)里面可以是列表、字符串浇辜、元組券敌、字典等
    注:
    定義一個(gè)空的集合不能用:set1 = {},這樣set1的類型是dict柳洋,所以應(yīng)該用:set1 = set()
添加元素

add()方法待诅,例如:num1.add(6),就會(huì)加進(jìn)去了熊镣,但只能加一個(gè)數(shù)據(jù)卑雁,而且不能加list、dict等绪囱,可以加tuple

移除元素

remove()方法测蹲,例如:num1.remove(1),如果刪除的內(nèi)容不存在則會(huì)報(bào)錯(cuò)鬼吵,如果希望刪除的數(shù)據(jù)即使不存在也不會(huì)報(bào)錯(cuò)扣甲,那么可以用discard()方法
注:
  因?yàn)榧蠠o(wú)序,所以無(wú)法索引齿椅,要讀取里面數(shù)據(jù)可以用for一個(gè)個(gè)讀取出來(lái)琉挖,也能用in來(lái)判斷启泣,或者把他變成一個(gè)列表等等

交集

使用intersection()方法,或者用&示辈,舉例:

>>> a = {1,2,3,5,7}
>>> b = {2,4,5,6}
>>> a.intersection(b)
{2, 5}
>>> a & b
{2, 5}
并集

使用union()方法寥茫,或者用|,舉例:

>>> a = {1,2,3,5,7}
>>> b = {2,4,5,6}
>>> a.union(b)
{1, 2, 3, 4, 5, 6, 7}
>>> b.union(a)
{1, 2, 3, 4, 5, 6, 7}
>>> a | b
{1, 2, 3, 4, 5, 6, 7}
去不同

比如要找出兩個(gè)集合的不同內(nèi)容顽耳,可以將兩個(gè)集合相減坠敷,舉例:

>>> a = {1,2,3,4,5}
>>> b = {1,5,6}
>>> a-b
{2, 3, 4}
#可以看出結(jié)果就是將a中有的減去b中有的剩下的值

這里放上來(lái)一道網(wǎng)申的筆試題,感覺(jué)用集合解決太完美:

現(xiàn)在有一個(gè)數(shù)組射富,其值為從1到10000的連續(xù)增長(zhǎng)的數(shù)字膝迎。出于某次偶然操作,導(dǎo)致這個(gè)數(shù)組中丟失了某三個(gè)元素胰耗,同時(shí)順序被打亂限次,現(xiàn)在需要你用最快的方法找出丟失的這三個(gè)元素,并且將這三個(gè)元素根據(jù)從小到大重新拼接為一個(gè)新數(shù)字柴灯,計(jì)算其除以7的余數(shù)卖漫。 例:丟失的元素為336,10赠群,8435羊始,得到的新數(shù)字為103368435,除以七的余數(shù)為2查描。
輸入描述:

輸入數(shù)據(jù)為一行突委,包含9997個(gè)數(shù)字,空格隔開(kāi)冬三。
輸出描述:
輸出為一行匀油,包含一個(gè)數(shù)字。

這道題最主要的問(wèn)題就是用最快方法找出集合1到1w里面沒(méi)有的3個(gè)數(shù)勾笆,如果用for循環(huán)遞歸一個(gè)個(gè)比對(duì)敌蚜,顯然花的時(shí)間不是一點(diǎn)兩點(diǎn),于是這里就可以用到集合相減找不同來(lái)實(shí)現(xiàn)窝爪,把兩種方式的代碼都放出來(lái)如下:

#用迭代的方式
li = input().split()
li.sort()
li_t = []
for i in range(1,10000):
#一個(gè)個(gè)用if去判斷
    if str(i) not in li:
        li_t.append(i)

result = ''
for each in li_t:
    result += str(each)
print(int(result)%7)

#用集合的方式
li = set(input().split())
li2 = set(str(i) for i in range(1,10000))
#創(chuàng)建一個(gè)1到10000的集合然后和輸入的集合相減弛车,瞬間就得到那3個(gè)沒(méi)有的了
li_result = list(li2 - li)
li_result.sort()
result = ''
for each in li_result:
    result += each
print(int(result)%7)

最終雖然兩個(gè)都能實(shí)現(xiàn),但是迭代花的時(shí)間確是集合的幾十倍蒲每,所以可以看出集合在某些場(chǎng)景下應(yīng)用的強(qiáng)大能力

更多集合操作參考

https://www.cnblogs.com/sunyang945/p/7859962.html

不可變集合(frozenset)

相當(dāng)于集合和元組的集合帅韧,不可變。通過(guò)frozenset()函數(shù)定義啃勉,舉例:set2 = frozenset([1,2,3,3,2,1])

更多參考

https://blog.csdn.net/weixin_37887248/article/details/81565468

字典(dict)

定義

(1)用{}定義忽舟,鍵值對(duì)引號(hào)隔開(kāi),例如:dic = {'a':'admin','b':'book','c':'cook'},則dic['b']就是'book'
注:
在python3.6以前的版本當(dāng)中叮阅,字典都是無(wú)序的刁品,如果希望使用有序字典,可以使用collections下的OrderedDict類浩姥;而在3.6及以后的版本當(dāng)中挑随,字典都是有序的了
(2)往dict()中插入元組/列表定義,舉例:

>>> a = [(1,'one'),[2,'two']]
>>> dic1 = dict(a)
>>> dic1
{1: 'one', 2: 'two'}

注:
dict()能強(qiáng)轉(zhuǎn)成字典類型勒叠,但是str不能直接轉(zhuǎn)成dict兜挨,舉例:

>>> dict("{'a':1,'b':2}")
Traceback (most recent call last):
  File "<pyshell#270>", line 1, in <module>
    dict("{'a':1,'b':2}")
ValueError: dictionary update sequence element #0 has length 1; 2 is required

所以這時(shí)候可以用eval()函數(shù)來(lái)轉(zhuǎn)成dict,舉例:

>>> a = eval("{'a':1,'b':2}")
>>> a
{'b': 2, 'a': 1}
>>> type(a)
<class 'dict'>

(3)用dict()直接指定鍵值對(duì)定義眯分,例如:dic1 = dict(x='abc',y='def')
注:
  第三種方式鍵是不加引號(hào)的拌汇,并且關(guān)鍵字會(huì)根據(jù)鍵來(lái)排序,例如:

>>> dic1 = dict(x='abc',y='def',z='ghi')
>>> dic1
{'z': 'ghi', 'x': 'abc', 'y': 'def'}

注2:
  像列表弊决、字典等數(shù)據(jù)類型里面還能放像函數(shù)噪舀、類之類的數(shù)據(jù),舉例:

def abc(x, y):
    print(x+y)

class XYZ():
    def __init__(selt,x):
        print(x)
    a = 50

a = {'a':1, 'b':abc, 'c':abc(1000,1000), 'd':lambda x,y : print(x+y), 'e': XYZ, 'f': XYZ(10000)}
#b和c都是函數(shù)飘诗,但b沒(méi)傳參數(shù)与倡,c傳了參數(shù),d是沒(méi)傳參的匿名函數(shù)昆稿,e是沒(méi)傳參的類纺座,f是傳參的類
#因?yàn)閏和f都傳了參數(shù),所以調(diào)用時(shí)就已經(jīng)執(zhí)行了溉潭,結(jié)果會(huì)先輸出200和1000净响,但是之后再調(diào)用就不會(huì)執(zhí)行了(其已經(jīng)變成函數(shù)的返回值,這里沒(méi)有岛抄,所以是None)
a['b'](1, 1)  #調(diào)用abc函數(shù)别惦,并傳入?yún)?shù)1和2
print(a['c'])        #輸出執(zhí)行過(guò)參數(shù)為3和4的abc函數(shù)返回值狈茉,因?yàn)閍bc沒(méi)返回夫椭,所以輸出None
a['d'](5, 5)  #調(diào)用lambda函數(shù)
print(a['e'].a)  #調(diào)用類XYZ的a屬性
a['e'](100)     #調(diào)用類,因?yàn)閭魅肓藚?shù)氯庆,執(zhí)行__init__函數(shù)

結(jié)果為:
2000  #定義a時(shí)第三個(gè)參數(shù)的輸出
10000  #定義a時(shí)最后一個(gè)參數(shù)的輸出
2
None
10
50
100
修改

直接給鍵賦值就好了蹭秋,例如上面的dic1:

>>> dic1['x']='aaa'
{'z': 'ghi', 'x': 'aaa', 'y': 'def'}

如果是不存在的鍵就會(huì)新建這個(gè)鍵值對(duì)

有序字典

默認(rèn)字典是根據(jù)hash之類的原理來(lái)排序的,如果希望字典的順序可以像類似列表那樣按順序排的話堤撵,可以使用OrderedDict仁讨,具體參考下面鏈接:
http://c.biancheng.net/view/2438.html

內(nèi)置函數(shù)
fromkeys(鍵[,值])

創(chuàng)建并返回一個(gè)統(tǒng)一值的新字典,其中可以設(shè)置鍵和值实昨,舉例:

>>> d1={}
>>> d1.fromkeys((1,2,3))    #創(chuàng)建一個(gè)字典洞豁,并定義3個(gè)鍵1、2、3
{1: None, 2: None, 3: None}
>>> d1.fromkeys((1,2,3),1)  #定義3個(gè)鍵并同時(shí)賦值為1
{1: 1, 2: 1, 3: 1}

他只能給所有鍵設(shè)置同一個(gè)值丈挟,所以不要以為可以通過(guò)傳入列表刁卜、元組來(lái)依次賦值,比如:

>>> d1.fromkeys((1,2,3),(4,5,6))
{1: (4, 5, 6), 2: (4, 5, 6), 3: (4, 5, 6)}  #結(jié)果不是{1:4, 2:5, 3:6}曙咽,而是值都為(4, 5, 6)

可以看出其還是給所有元素都設(shè)置了同一個(gè)值

keys()

返回字典的所有鍵名蛔趴,例如:

>>> d1={1:2,2:'two'}
>>> d1.keys()
dict_keys([1, 2])
values()

返回字典的所有值,例如:

>>> d1={1:2,2:'two'}
>>> d1.values()
dict_values([2, 'two'])
items()

返回字典的所有鍵值對(duì)例朱,例如:

>>> d1={1:2,2:'two'}
>>> d1.items()
dict_items([(1, 2), (2, 'two')])

注:
  keys孝情、valuesitems常用于循環(huán)輸出字典洒嗤,例如:

for key in d1.keys()
    print("循環(huán)輸出所有的鍵:",key)
get()

根據(jù)鍵獲取值箫荡,一般常用d1[鍵]輸出值,但如果鍵不存在烁竭,這種方法就會(huì)報(bào)錯(cuò)菲茬,所以用get就更寬松,比如對(duì)上面的d1:d1.get(1)結(jié)果就是2派撕,但是d1.get(3)不輸出也不會(huì)報(bào)錯(cuò)婉弹,如果用print打印結(jié)果會(huì)是none,我們還可以用get來(lái)判斷輸出终吼,有就輸出值镀赌,沒(méi)有就輸出我們想要的內(nèi)容,比如:

>>> d1.get(3,'nothing')
nothing    #因?yàn)?不存在所以輸出nothing际跪,如果3在就輸出3的值

注:
get可以判斷鍵在不在字典商佛,in和not in也可以,比如上面的:1 in d1結(jié)果就是True
注2:
因?yàn)殒I是唯一的姆打,所以可以用get(鍵)dict[鍵]來(lái)獲取值良姆,反過(guò)來(lái)如果想通過(guò)值來(lái)獲取鍵,可以通過(guò)get條件判斷來(lái)進(jìn)行遍歷,舉例:

>>> d
{2: 2, 3: 6, 5: 1, 6: 1, 7: 1, 9: 1}
>>> [i for i in d if d.get(i) == 1]
#鏈表推導(dǎo)式當(dāng)i(鍵)=1(值)時(shí)勺爱,輸出i
[5, 6, 7, 9]
>>> [i for i in d if d.get(i) == 6]
[3]

如果是要求最值的鍵甲献,則可以用內(nèi)置的min/max函數(shù),舉例:

>>> d
{2: 2, 3: 6, 5: 1, 6: 1, 7: 1, 9: 1}
>>> max(d, key=d.get)
3
clear()

清空字典痊剖,例如:d1.clear()結(jié)果d1就變成{}
注:
  d1={}會(huì)使d1變成空,但是其原來(lái)指向的字典沒(méi)變成空垒玲,而clear才是真正意義上的清空陆馁,例如:

>>> d1={1:2,2:'two'}
>>> d2 = d1  #此時(shí)d2和d1指向同一個(gè)地址,可以用id(d2)查看
>>> d1 = {}
>>> d1  #d1變成空
{}
>>> d2  #d2還是指向d1原來(lái)的地方合愈,而原來(lái)指向的地方?jīng)]變成空叮贩,所以d2沒(méi)變成空
{1: 2, 2: 'two'}
###這次使用clear
>>> d1={1:2,2:'two'}
>>> d2 = d1
>>> d1.clear()
>>> d1
{}
>>> d2  #這次d2和d1一樣都清空了
{}
copy()

淺拷貝击狮,和賦值不太一樣,賦值就相當(dāng)于確定了指向益老,所以用id()查看會(huì)發(fā)現(xiàn)賦值后原來(lái)的字典和賦值的字典地址是一樣的帘不,但copy的結(jié)果地址是不同的,所以如果原字典內(nèi)容改變杨箭,賦值的字典會(huì)跟著改變寞焙,但copy的字典不變(copy有點(diǎn)像列表里的整個(gè)分段賦值)

pop()

括號(hào)里給定鍵彈出對(duì)應(yīng)的值

popitem()

括號(hào)里沒(méi)參數(shù),隨機(jī)彈出一個(gè)項(xiàng)

setdefault()

get有點(diǎn)像互婿,能輸出鍵對(duì)應(yīng)的值捣郊,但不同的是如果鍵不存在他會(huì)新加進(jìn)去,例如:d1.setdefault(1)結(jié)果是2慈参,但d1.setdefault(3)呛牲,結(jié)果d1會(huì)變成:{1: 2, 2: 'two', 3: None} ,新建同時(shí)還可以賦值驮配,例如:d1.setdefault(5,"aaa")娘扩,d1就會(huì)變成:{1: 2, 2: 'two', 3: None, 5: 'aaa'}

update()

把一個(gè)字典的東西加到另一個(gè)字典里去,例如:

>>> d2={6:'bbb'}
>>> d1.update(d2)
{1: 2, 2: 'two', 3: None, 5: 'aaa', 6: 'bbb'}    #加入了d2的內(nèi)容
for輸出
  • 方法1:其輸出是只輸出鍵而不是值壮锻,所以如果想輸出值就要輸出字典的對(duì)應(yīng)項(xiàng)琐旁,舉例:
dict1 = {'a':'one','b':'two','c':'three'}
for each in dict1:
    print("%s -> %s" % (each,dict1[each]),end=' ')  #each只是鍵
結(jié)果為:a -> one b -> two c -> three 
  • 方法2:通過(guò)將字典放入迭代器,然后分別保存鍵猜绣、值灰殴,舉例:
dict1 = {'a':'one','b':'two','c':'three'}
for key,value in dict1.items():    #分別賦值鍵值到key和value
    print(key,value,end=' ')
結(jié)果為:b two a one c three 
字典和json區(qū)別

字典和json樣式十分相似,雖然前者是數(shù)據(jù)類型掰邢,后者是一種格式牺陶,但最明顯的區(qū)別就是字典可以用單引號(hào),而在json中得用雙引號(hào)辣之,所以如果想將一個(gè)字典以json格式傳遞時(shí)掰伸,記得將單引號(hào)都替換成雙引號(hào)

Ellipsis

這個(gè)是python一個(gè)自帶常量,和...是等價(jià)的(偶然輸入...發(fā)現(xiàn)竟然沒(méi)有報(bào)錯(cuò)怀估,原來(lái)還有內(nèi)置這樣的常量)狮鸭,意思相當(dāng)于什么都沒(méi)有,或者在數(shù)組之類的地方起省略意義奏夫,一般可以和pass相互替換怕篷,舉例:

>>> ...
Ellipsis
>>> print(...)
Ellipsis
>>> print(Ellipsis)
Ellipsis
字典效率历筝、順序
  • 字典的內(nèi)存開(kāi)銷大酗昼,但是查詢快,而自定義的對(duì)象梳猪、以及python提供的對(duì)象也都是用字典來(lái)包裝的
  • 在python3.6之前麻削,字典是無(wú)序的蒸痹,因此其存儲(chǔ)順序和元素添加的順序有關(guān)(基于哈希表內(nèi)部的原理,哈希沖突的處理等)呛哟,并且添加數(shù)據(jù)有可能改變已有數(shù)據(jù)的順序(例如哈希表內(nèi)部達(dá)到一定占用率時(shí)會(huì)進(jìn)行擴(kuò)容叠荠,將重新開(kāi)辟空間依次存入,導(dǎo)致順序改變)扫责,所以如果想要使用有序字典榛鼎,可以使用collections模塊下的OrderedDict;python3.6開(kāi)始鳖孤,字典都是有序的了

其他數(shù)據(jù)類型

隊(duì)列(queue)

先入先出者娱,且一個(gè)數(shù)據(jù)只能取一次,需要import queue苏揣,使用也很簡(jiǎn)單黄鳍,先新建一個(gè)Queue對(duì)象,然后要往隊(duì)列加?xùn)|西就用put()平匈,取東西就用get()就行了(用get如果隊(duì)列為空則會(huì)卡住框沟,所以也可以用get_nowait,當(dāng)隊(duì)列為空時(shí)會(huì)出異常)增炭,查看用qsize()忍燥,舉例:

q = queue.Queue()   #新建一個(gè)隊(duì)列
q.put("one")
q.put("two")
q.put([1,2,3]) 
q.qsize()       #結(jié)果為3
q.get()     #結(jié)果為one
q.get()     #結(jié)果為two
q.get()     #結(jié)果為[1,2,3]
q.get()     #程序卡住,如果是q.get_nowait()則會(huì)報(bào)出空異常

如果想要限制隊(duì)列大小隙姿,可以在新建對(duì)象時(shí)里面加入maxsize參數(shù)灾前,比如:

q = queue.Queue(maxsize=3)

此時(shí)一旦超過(guò)隊(duì)列長(zhǎng)度就會(huì)卡住,然后查看put和get會(huì)發(fā)現(xiàn)里面都有個(gè)block(默認(rèn)為True)和timeout(默認(rèn)為None)參數(shù)孟辑,前者代表是否卡住哎甲,后者代表卡住幾秒,所以我們可以設(shè)置為False或者設(shè)置timeout時(shí)長(zhǎng)來(lái)避免卡住饲嗽,比如:

c.get(block=False)  #當(dāng)隊(duì)列為空時(shí)報(bào)錯(cuò)炭玫,不卡住
c.get(timeout=1)        #當(dāng)隊(duì)列為空時(shí)延時(shí)一秒,然后報(bào)錯(cuò)
#put方法同理
實(shí)例

(通過(guò)多線程和隊(duì)列實(shí)現(xiàn)生產(chǎn)者消費(fèi)者順序購(gòu)買產(chǎn)品問(wèn)題)

import threading
import time
import queue

def Producer():
   count = 1
   while True:
      q.put("產(chǎn)品%d" % count)
      print("\033[42;m生產(chǎn)第%d個(gè)產(chǎn)品\033[0m" % count)
      time.sleep(0.3)
      count += 1
      print("\033[45;m目前還剩%d個(gè)產(chǎn)品\033[0m" % q.qsize())

def Consumer(name):
   num = 0
   while True:
      print("\033[43;m%s購(gòu)買了%s\033[0m" % (name, q.get()))
      num += 1
      print("\033[45;m%s共買了%d個(gè)產(chǎn)品\033[0m" % (name, num))
      time.sleep(1)

q = queue.Queue()
producer = threading.Thread(target=Producer)
consumerA = threading.Thread(target=Consumer, args=("熱心市民A",))
consumerB = threading.Thread(target=Consumer, args=("熱心市民B",))
producer.start()
consumerA.start()
consumerB.start()
棧(stack)

和前面的隊(duì)列十分相似貌虾,也是導(dǎo)入queue吞加,但是新建的對(duì)象是LifoQueue,其他和隊(duì)列一樣尽狠,當(dāng)然用列表的append()pop()也可以實(shí)現(xiàn)衔憨。

優(yōu)先級(jí)隊(duì)列

在queue中還有一個(gè)PriorityQueue是用來(lái)實(shí)現(xiàn)優(yōu)先級(jí)隊(duì)列的,其和上面的區(qū)別就是在put的時(shí)候傳入的是個(gè)元組袄膏,里面同時(shí)設(shè)置優(yōu)先值践图,值越小越優(yōu)先,舉例:

q = queue.PriorityQueue()
q.put((2, "two"))
q.put((5, "five"))
q.put((0, "zero"))
q.put((1, "one"))
q.get()         #(0, 'zero')
q.get()         #(1, 'one')
q.get()         #(2, 'two')
q.get()         #(5, 'five')
雙向隊(duì)列

前面的棧和隊(duì)列都是單向的沉馆,一旦定義以后就只能從頭或者尾其中一邊操作码党,在list中雖然可以用pop來(lái)實(shí)現(xiàn)棧的功能德崭,但是卻無(wú)法實(shí)現(xiàn)隊(duì)列的功能,所以這里可以用雙向隊(duì)列揖盘,需要使用到collectionsdeque眉厨,可以直接用from import導(dǎo)入deque,然后通過(guò)append()兽狭、appendleft()憾股、pop()popleft()來(lái)實(shí)現(xiàn)棧和隊(duì)列箕慧,舉例:

from collections import deque
a = deque()     # deque([])
a.append(5)     # deque([5])
a.appendleft(4) # deque([4, 5])
a.appendleft(3) # deque([3, 4, 5])
a.pop()         #5
a.popleft()     #3
計(jì)數(shù)器

在前面的collections里有個(gè)Counter還是作為計(jì)數(shù)器的存在荔燎,其可以計(jì)算一個(gè)數(shù)據(jù)結(jié)構(gòu)當(dāng)中各元素出現(xiàn)的次數(shù),并返回一個(gè)字典销钝,需要導(dǎo)入Counter有咨,舉例:

from collections import Counter
c = Counter([1,2,3,32,1,2,1,2,2,3,4])
#計(jì)算該列表里各元素個(gè)數(shù)
print(c)
結(jié)果為:Counter({2: 4, 1: 3, 3: 2, 32: 1, 4: 1})

python內(nèi)置類型

數(shù)值類型
int
float
bool
complex  復(fù)數(shù)類型
迭代類型
iterator  迭代器
generator  生成器
序列類型
list
bytes
bytearray  字節(jié)流,數(shù)據(jù)只能是0或1
memoryview  二進(jìn)制序列
range
tuple
str
array  數(shù)組蒸健,相比于list座享,其所有數(shù)據(jù)必須為同一類型,因此內(nèi)存空間也是連續(xù)的似忧,效率更高
映射
dict
集合
set
frozenset  不可變集合

注:集合和映射在python中的實(shí)現(xiàn)差不多渣叛,因此效率都比較高

上下文管理器
with
其他
模塊類型
類對(duì)象
類實(shí)例
函數(shù)類型
方法類型
代碼類型
object對(duì)象
type類型
ellipsis類型
notimplemented類型

序列類

分類

容器序列:內(nèi)部可以存放任意類型數(shù)據(jù),如list盯捌、tuple淳衙、deque
扁平序列:只能存放相同類型的數(shù)據(jù),如str饺著、array箫攀、bytes、bytearray
可變序列:內(nèi)容可以修改幼衰,如list靴跛、array、deque渡嚣、bytearray
不可變序列:內(nèi)容不能修改梢睛,如tuple、str识椰、bytes

相關(guān)基類

collections.abc下提供了Sequence(不可變序列)/MutableSequence(可變序列)類

+/extend/+=區(qū)別
  • +:必須為相同類型绝葡,并且返回一個(gè)新的序列對(duì)象,源碼(基于UserList稍作修改):
def __add__(self, other):
    return self.__class__(self + self.__class__(other))
  • extend:只要是序列類就行腹鹉,也是在原先對(duì)象中改變藏畅,本質(zhì)就是for循環(huán),依次append种蘸,源碼:
def extend(self, values):
    'S.extend(iterable) -- extend sequence by appending elements from the iterable'
    for v in values:
        self.append(v)
  • +=:只要是序列類就行墓赴,并且在原先的對(duì)象中進(jìn)行改變,內(nèi)部實(shí)際是調(diào)用extend方法航瞭,源碼:
def __iadd__(self, values):
    self.extend(values)
    return self
切片
相關(guān)操作
>>> a = [1,2,3,4,5]
>>> a[2:] = [5,6,7]
# 替換第三個(gè)元素開(kāi)始的后面所有元素
>>> a
[1, 2, 5, 6, 7]
>>> a[:0] = [0]
# 在頭部插入元素
>>> a
[0, 1, 2, 5, 6, 7]
>>> a[2:] = [9, 8, 7]
>>> a
[0, 1, 9, 8, 7]
>>> a[::2] = [10, 20, 30]
# 隔一個(gè)改一個(gè)元素诫硕,右邊迭代的長(zhǎng)度必須和左邊切片的長(zhǎng)度相等
>>> a
[10, 1, 20, 8, 30]
>>> a[:1] = []
# 刪除第一個(gè)元素
>>> a
[1, 20, 8, 30]
>>> del a[::2]
# 隔一個(gè)刪一個(gè)元素
>>> a
[20, 30]
>>> del a[:1]
# 刪除第一個(gè)元素
>>> a
[30]
>>> a[0:0] = [1,2,3]
# 往第0個(gè)位置插入3個(gè)元素
>>> a
[1, 2, 3, 30]
實(shí)現(xiàn)原理

在通過(guò)切片索引時(shí),會(huì)自動(dòng)將切片語(yǔ)法轉(zhuǎn)成slice對(duì)象刊侯,該對(duì)象包括起始位置章办、結(jié)束位置和步長(zhǎng)三個(gè)參數(shù),舉例:

a = [1,2,3,4,5]
print(a[0::2])
print(a[slice(0, None, 2)])

# [1, 3, 5]
# [1, 3, 5]

可以看出兩個(gè)結(jié)果都是一樣的滨彻,然后對(duì)象只需要實(shí)現(xiàn)__getitem__方法藕届,在內(nèi)部處理slice的處理邏輯即可,我們可以自己模擬實(shí)現(xiàn)一個(gè)自己的slice對(duì)象和相關(guān)的切片處理邏輯亭饵,舉例:

class MySlice:
    def __init__(self, start=None, end=None, step=None):
        self.start = start
        self.end = end
        self.step = step
    def get_slice(self):
        return self.start, self.end, self.step

class Test:
    def __init__(self, data=[]):
        self.data = data

    def __setitem__(self, item, value):
        if isinstance(item, MySlice):
            start, end, step = self.parse_slice(item)
            value = iter(value)
            for i in range(start, end, step):
                self.data[i] = next(value)
        else:
            self.data[item] = value

    def __getitem__(self, item):
        cls = type(self)
        if isinstance(item, MySlice):
            start, end, step = self.parse_slice(item)
            return cls([self.data[i] for i in range(start, end, step)])
            # 重新實(shí)例化一個(gè)自身對(duì)象返回
        return cls(self.data[item])

    def parse_slice(self, s):
        """自定義切片設(shè)置默認(rèn)值"""
        start, end, step = s.get_slice()
        if start == None:
            start = 0
        if end == None:
            end = len(self.data)
        if step == None:
            step = 1
        return start, end, step

    def __str__(self):
        return str(self.data)

li = Test([1,2,3,4,5])
sli = MySlice(0, None, 2)
print(li[sli])
li[sli] = [9, 8, 7]
print(li)

# [1, 3, 5]
# [9, 2, 8, 4, 7]

映射類

不可變映射類

MappingProxyType休偶,繼承于Mapping類,相當(dāng)于一個(gè)只讀的字典辜羊,源碼如下:

MappingProxyType = type(type.__dict__)

我們可以從types模塊下導(dǎo)入踏兜,使用舉例:

from types import MappingProxyType

di = MappingProxyType({"a":1, "b":2})
print(di)
di["a"] = 2
# 不允許修改,這句會(huì)報(bào)錯(cuò)
可變映射類

dict八秃,繼承于MutableMapping類碱妆,而該類繼承于Mapping類

UserDict

可以理解為用python實(shí)現(xiàn)的字典,由于python中的列表昔驱、字典都是用C寫的疹尾,內(nèi)部有些魔法方法之類的未必能生效,因此如果希望繼承一個(gè)字典的話骤肛,那么可以繼承collection模塊下提供的UserDictcollection下還提供了UserList/UserStr與之同理)纳本,舉例:

from collections import UserDict
class A(dict):
    def __setitem__(self, item, value):
        super().__setitem__(item, value*2)

class B(UserDict):
    def __setitem__(self, item, value):
        super().__setitem__(item, value*2)

a = A(x=1)
b = B(x=1)
print(a)
print(b)

# {'x': 1}
# {'x': 2}

可以看到繼承自dict的類,實(shí)例化的對(duì)象的__setitem__方法沒(méi)生效腋颠,但是繼承自UserDict的卻生效了

defaultdict

UserDict一樣是dict的子類饮醇,初始化時(shí)可以指定當(dāng)索引內(nèi)容不存在時(shí)的默認(rèn)值類型,本質(zhì)是內(nèi)部實(shí)現(xiàn)了__missing__的魔法方法秕豫,當(dāng)key的值獲取失敗時(shí)朴艰,則會(huì)設(shè)置一個(gè)默認(rèn)類型的值,舉例:

def default():
    return {
        "name": "aaa",
        "age": 18
    }

a = defaultdict(default)
# 指定默認(rèn)是一個(gè)固定內(nèi)容的字典混移,傳入的默認(rèn)對(duì)象必須是可調(diào)用的祠墅,這里傳入一個(gè)函數(shù),也可以傳入list歌径、dict等數(shù)據(jù)類型
print(a["x"])
a["y"] = 2
print(a)

# {'name': 'aaa', 'age': 18}
# defaultdict(<function default at 0x00000162E1A33EA0>, {'x': {'name': 'aaa', 'age': 18}, 'y': 2})
可哈希對(duì)象
  • 對(duì)于字典的key毁嗦、集合的元素都必須是可哈希的才能存入
  • 不可變對(duì)象都是可hash的,如:str回铛、fronzeset狗准、tuple克锣,如果希望自己定義的類可哈希,那么必須實(shí)現(xiàn)__hash__的魔法方法
    注:
    不可變對(duì)象如果是可哈希的腔长,還必須滿足子元素也都是可哈希的條件袭祟,舉例:
print(hash((1,2,3)))
# 元組內(nèi)部維護(hù)的數(shù)字是不可變的,因此可哈希
li = [1,2,3]
print(hash((1,li)))
# 元組內(nèi)部有一個(gè)可變的列表捞附,不可哈希巾乳,因此會(huì)報(bào)錯(cuò)

# 2528502973977326415
# TypeError: unhashable type: 'list'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鸟召,隨后出現(xiàn)的幾起案子胆绊,更是在濱河造成了極大的恐慌,老刑警劉巖欧募,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件压状,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡跟继,警方通過(guò)查閱死者的電腦和手機(jī)何缓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)还栓,“玉大人碌廓,你說(shuō)我怎么就攤上這事∈:校” “怎么了谷婆?”我有些...
    開(kāi)封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)辽聊。 經(jīng)常有香客問(wèn)我纪挎,道長(zhǎng),這世上最難降的妖魔是什么跟匆? 我笑而不...
    開(kāi)封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任异袄,我火速辦了婚禮,結(jié)果婚禮上玛臂,老公的妹妹穿的比我還像新娘烤蜕。我一直安慰自己,他們只是感情好迹冤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布讽营。 她就那樣靜靜地躺著,像睡著了一般泡徙。 火紅的嫁衣襯著肌膚如雪橱鹏。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音莉兰,去河邊找鬼挑围。 笑死,一個(gè)胖子當(dāng)著我的面吹牛糖荒,可吹牛的內(nèi)容都是我干的杉辙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼寂嘉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼奏瞬!你這毒婦竟也來(lái)了枫绅?” 一聲冷哼從身側(cè)響起泉孩,我...
    開(kāi)封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎并淋,沒(méi)想到半個(gè)月后寓搬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡县耽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年句喷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兔毙。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡唾琼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出澎剥,到底是詐尸還是另有隱情锡溯,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布哑姚,位于F島的核電站祭饭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏叙量。R本人自食惡果不足惜倡蝙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一绞佩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧析既,春花似錦、人聲如沸谆奥。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)宰译。三九已至檐蚜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沿侈,已是汗流浹背闯第。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缀拭,地道東北人咳短。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蛛淋,于是被迫代替她去往敵國(guó)和親咙好。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,383評(píng)論 0 5
  • 在C語(yǔ)言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長(zhǎng)度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來(lái)閱讀 3,343評(píng)論 0 2
  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說(shuō)明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí)褐荷,會(huì)觸發(fā)此異常勾效。 O...
    我想起個(gè)好名字閱讀 5,317評(píng)論 0 9
  • 概要 64學(xué)時(shí) 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,208評(píng)論 0 3
  • 我要背著光走, 不讓眼睛被它灼得通紅叛甫, 把影子踩在前頭层宫, 而世界拋給背后。 沒(méi)有誰(shuí)彷徨得了我的決定其监, 我是特立獨(dú)行的自由
    山屈生閱讀 253評(píng)論 1 2