-
Dq的方法自己要學(xué)著看一下。
查看全部 -
Dq也是c語言寫的性能非常的高。
查看全部 -
_asdict會得到一個(gè)有序的字典,這個(gè)有序指的是將key進(jìn)行排序。
查看全部 -
Python是一門解釋性語言,也就是會將程序先編譯成字節(jié)碼PyC,PVC的加載速度會比較快。
查看全部 -
Pupil的進(jìn)階講解。
查看全部 -
deque雙端隊(duì)列
list和deque通常被當(dāng)作容器,存儲相同類型元素;tuple通常被當(dāng)作一個(gè)類對象,存儲不同類型元素
deque創(chuàng)建:
deque(iterable)(list, tuple, dict都是iterable的,傳入dict時(shí)key作為deque中的元素)
deque方法:
pop(),popleft(),index(),clear(),insert(),remove(),extend(),extendleft(),count()...
最關(guān)鍵的:
deque是線程安全的(多線程編程時(shí),往里put元素?zé)o需加鎖),list不是線程安全的
查看全部 -
count_dict?=?{} all?=?['a','b','c','a','b','b'] for?i?in?all: ????if?i?not?in?count_dict: ????????count_dict[i]?=?0 ????count_dict[i]?+=?1 print(count_dict) ==>{'a':?2,?'b':?3,?'c':?1}
當(dāng)dict中沒有對應(yīng)的key時(shí)會拋出keyError異常,所以一般做法是先判斷dict中是否有該key,若沒有先初始化
忘記判斷怎么辦?defaultdict會解決
count_dict?=?defaultdict(int) all?=?['a','b','c','a','b','b'] for?i?in?all: ????count_dict[i]?+=?1 print(count_dict) ==>defaultdict(<class?'int'>,?{'a':?2,?'b':?3,?'c':?1})
defaultdict:
當(dāng)你訪問一個(gè)不存在的key時(shí)==>dict[key],defaultdict會自動創(chuàng)建鍵值對,value根據(jù)創(chuàng)建defaultdict時(shí)傳入的類型對象或函數(shù)對象決定
類型對象:
dic_1?=?defaultdict(int) dic_2?=?defaultdict(tuple) dic_3?=?defaultdict(list) dic_4?=?defaultdict(str) dic_5?=?defaultdict(set) print(dic_1['a']) print(dic_2['a']) print(dic_3['a']) print(dic_4['a']) print(dic_5['a']) ==> 0 () [] set()
函數(shù)對象:
可以定義嵌套結(jié)構(gòu),如下dict嵌套dict
def?gen_default(): ????return?{ ????????'name':'', ????????'member_nums':0 ????} default_dict?=?defaultdict(gen_default)?????#注意不能加(),因?yàn)槭菍ο蟛皇欠椒?print(default_dict['group1']) ==>{'name':?'',?'member_nums':?0}
查看全部 -
namedtuple是一個(gè)類
User?=?namedtuple('User',['name','age','height'])?#類名,[屬性] user?=?User(name='bobby',age=29,height=175) print(user.name,user.age,user.height) ==>bobby?29?175
為什么不直接class一個(gè)類,還要弄一個(gè)namedtuple出來?
1、class一個(gè)類要定義很多變量,代碼量增加,空間復(fù)雜
2、在數(shù)據(jù)處理時(shí),經(jīng)常需要從數(shù)據(jù)庫中讀入數(shù)據(jù),從數(shù)據(jù)庫中讀出的數(shù)據(jù)其實(shí)就是一個(gè)tuple
復(fù)習(xí)一下*args,**kwargs
如果不指明參數(shù)名稱,全部算在args這個(gè)tuple中
如果指明參數(shù)名稱,就算在kwargs這個(gè)dict中
def?ask(*args,**kwargs):???kwargs:{}????args:('bobby',29) ????pass ask('bobby',29)
def?ask(*args,**kwargs):???args:()????kwargs:{'name':'bobby','age':29} ????pass ???? ask(name='bobby',age=29)
def?ask(*args,**kwargs):???kwargs:{'age':29}????args:('bobby') ????pass ask('bobby',age=29)
所以創(chuàng)建類的時(shí)候,參數(shù)也可以這樣寫:
user_tuple?=?('bobby',29,175) user?=?User(*user_tuple)
user_dict?=?{ ????'name':'bobby', ????'age':29, ????'height':175 } user?=?User(**user_dict)
namedtuple的常用函數(shù)
1、_make(iterable)(list, tuple, dict都是iterable的)創(chuàng)建namedtuple
user_list?=?["bobby",29,175] user_tuple?=?("bobby",29,175) user_dict?=?{ ????'name':'bobby', ????'age':29, ????'height':175 } user?=?User._make(user_list/user_tuple/user_dict)
和上面*args,**kwargs的區(qū)別在哪里呢?
*args,**kwargs靈活性更強(qiáng),但_make()不用加*/**且多一個(gè)list參數(shù)方式
例:數(shù)據(jù)庫中user表中的數(shù)據(jù)全部取出然后再加一個(gè)列
User?=?namedtuple('User',['name','age','height','edu'])? user?=?User(*user_tuple,'master')
User?=?namedtuple('User',['name','age','height','edu'])? user?=?User(**user_dict,edu='master')
_make()不行
2、_asdict()將namedtuple轉(zhuǎn)為dict
User?=?namedtuple("User",["name","age","height"]) user_tuple?=?("bobby",29,175) user?=?User(*user_tuple) user_dict?=?user._asdict() print(user_dict) ==>{'name':?'bobby',?'age':?29,?'height':?175}
查看全部 -
tuple的功能:
不可變、iterable
拆包
tuple不可變性不是絕對的(所以放進(jìn)tuple中的元素最好是不可變的)
tuple比list好的地方
????????????immutable(不可變)的重要性
????????????????????性能優(yōu)化:元素全為immutable的tuple會作為常量在編譯時(shí)確定
????????????????????線程安全(tuple本身加鎖)
????????????????????可以作為dict的key
????????????????????拆包特性
user_tuple?=?("bobby",29) name,age?=?user_tuple ==>bobby?29 user_tuple?=?("bobby",29,175,"beijing","edu") name,?*other?=?user_tuple print(name,other) ==>bobby?[29,?175,?'beijing',?'edu']
查看全部 -
tuple:不可變,可迭代對象iterable(實(shí)現(xiàn)了__iter__或者_(dá)_getitem__魔法函數(shù))
元祖的拆包:
用法:
user_tuple = ("bobby", 28, 178)
name, age, height = user_tuple
只想提取第一個(gè)參數(shù):
name, *other = user_tuple
輸出:
bobby, [29, 175]
tuple的不可變不是絕對的:
tuple內(nèi)部嵌套了可變對象(不太建議使用),嵌套對象可修改
tuple比list好用的地方:
immutable(不可變對象)的重要性:
①性能優(yōu)化(元素全部為不可變對象的tuple會作為常量在編譯時(shí)確定,因此產(chǎn)生如此顯著的速度差異)
②線程安全
③可以作為dict的key(immutable對象是可哈希的,dict key也是可哈希的,適合做字典的key)
使用list做key會報(bào)錯(cuò)提示:TypeError: unhashable type: 'list'
④拆包特性
如果拿c語言類比,tuple好比struct,list對應(yīng)的是array
查看全部 -
from collections import namedtuple
使用namedtuple可以創(chuàng)建一個(gè)類,返回一個(gè)帶有命名字段的新元祖子類
# namedtuple 相當(dāng)于創(chuàng)建了一個(gè)User類,里面含有name,age,height成員變量
# namedtuple是tuple的子類,
# 1、代碼比直接定義類更簡單
# 2、namedtuple比較節(jié)省空間,少了class里面很多內(nèi)置的變量
# 3、非常適用于創(chuàng)建簡單對象,特別用作數(shù)據(jù)處理
User = namedtuple("User",["name", "age", "height"])
user = User(name="bobby", age=29, height=178)
print(user.age, user.name, user.height)
# 應(yīng)用場景:user表數(shù)據(jù)全部取出然后加一個(gè)列edu,比較方便(pymysql,查詢返回結(jié)果是tuple)
User = namedtuple("User",["name", "age", "height", "edu"])
user = User(name="bobby", age=29, height=178)
user.edu = "master"
# 也可以通過傳入tuple或者dict來初始化namedtuple
User = namedtuple("User",["name", "age", "height"])
user_tuple = ("bobby", 29, 175)
user = User(*user_tuple)
user_dict = {
????????"name":"bobby",
????????"age":29,
????????"height":175
}
user = User(**user_dict)
#namedtuple實(shí)現(xiàn)原理:
點(diǎn)擊進(jìn)去namedtuple類看,找到python的一個(gè)內(nèi)置函數(shù)方法:
exec(class_definition, namespace) #把字符串當(dāng)做代碼執(zhí)行
繼續(xù)點(diǎn)擊class_definition,有個(gè)_class_template,點(diǎn)擊進(jìn)去,這個(gè)就是namedtuple的實(shí)質(zhì)
內(nèi)部代碼實(shí)現(xiàn)原理實(shí)際上是生成一個(gè)class,里面的方法就是namedtuple具有的所有方法
其中包括_make、_replace、__repr__、_asdict、__getnewargs__方法
重點(diǎn)介紹_make、_asdict方法
_make方法可傳遞一個(gè)iterable可迭代對象
實(shí)際前面例子創(chuàng)建User對象時(shí),也可以用_make方法
User = namedtuple("User",["name", "age", "height"])
user_tuple = ("bobby", 29, 175)
user = User._make(user_tuple)
_asdict方法, 可以將tuple轉(zhuǎn)換成OrderedDict
User = namedtuple("User",["name", "age", "height"])
user_tuple = ("bobby", 29, 175)
user = User(*user_tuple)
user_info_dict = user._asdict()
因?yàn)閚amedtuple是繼承自tuple,所以它也支持拆包功能:
User = namedtuple("User",["name", "age", "height","edu"])
user = User(name="bobby", age=29, height=178, edu="master")
name, age, *other = user
查看全部 -
有大量數(shù)據(jù)需要做統(tǒng)計(jì)代碼量會比較大,可使用Counter類
from collections import Counter
users = ['bobby1','bobby2','bobby1','bobby2','bobby2','bobby3']
users_counter = Counter(users)
print(users_counter?)
Counter可以傳遞任何可迭代對象
users_counter = Counter("asdasdgdfwee")
Counter是dict子類,繼承自dict,它返回dict類型統(tǒng)計(jì)結(jié)果
?
users_counter.update("asdasdg") #?也可以進(jìn)行合并統(tǒng)計(jì),使用update方法
它也可以傳遞另外一個(gè)Counter對象
users_counter1 = Counter("asdasdgdfwee")
users_counter2 = Counter("sdf342zz")
users_counter1.update(users_counter2?)
users_counter.most_common(2) # 統(tǒng)計(jì)出現(xiàn)次數(shù)最多的前n個(gè)元素
它的內(nèi)部是通過_heapq堆數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,這個(gè)堆是專門解決這個(gè)topn問題,性能比自己遍歷更高
查看全部 -
ChainMap
from collections import ChainMap
user_dict1 = {'a':"rio1", "b":"rio2"}
user_dict2 = {'b':"rio3", "d":"rio3"}
for key, value in user_dict1.item():
????print(key,value)
for key, value in user_dict2.item():
????print(key,value)
如果類似上面的dict定義了多個(gè),就需要分別去遍歷多次item
ChainMap可以把所有dict連接起來一起遍歷。
new_dict = ChainMap(user_dict1,user_dict2)
for key, value in new_dict.item():
????xxxxxx
如果兩個(gè)字典存在相同的key,只會遍歷先找到的key,后面出現(xiàn)相同的key都不會遍歷
在原來的chainmap字典中再動態(tài)新增字典,返回一個(gè)新的ChainMap
new_chainmap = new_dict.new_child( {"aa":11,“bb":22} )
以列表形式把數(shù)據(jù)展示出來
print(new_dict.maps)
=> [{'a':"rio1", "b":"rio2"},?{'b':"rio3", "d":"rio3"}]
ChainMap并不是把多個(gè)數(shù)據(jù)合并變成一個(gè)dict,而是在上面加了一個(gè)訪問迭代器,并沒有拷貝到新的變量里。
new_dict.maps[0]['a'] = 'rio'
for key, value in new_dict.item():
? ? print(key,value)
查看全部 -
OrderedDict:有序字典
from collections import OrderedDict
它是dict的子類,它是有序的,其順序是:先添加的在前邊,后添加的在后
user_dict = OrderedDict()
user_dict['a'] = "rio1"
user_dict['c"] = "rio2"
user_dict["b"] = "rio3"
python3下dict和OrderedDict都是有序的,OrderedDict提供了額外的函數(shù)
pop_item可以不需要傳遞key并刪除最后一個(gè)item,pop需要傳遞key
user_dict.popitem()
user_dict.pop(key)
move_to_end("key"),把指定元素移到最后
拓展:
前面小結(jié)namedtuple的_asdict()返回的就是orderedDict
查看全部 -
from collections import defaultdict
傳統(tǒng)dict類型使用setdefault方法更加高效
defaultdict是dict的擴(kuò)展子類,它還會在鍵不存在的時(shí)候賦予默認(rèn)值
# defaultdict需要傳遞進(jìn)來一個(gè)可調(diào)用的對象,list和int都是可調(diào)用對象
default_dict = defaultdict(list)
default_dict['bobby']
key不存在時(shí)不會拋出異常,會在key不存在時(shí)調(diào)用傳遞進(jìn)來的可調(diào)用對象(以上例子為list),給key添加value。值是list的空數(shù)組。
如果傳遞的是int對象,則默認(rèn)值為0;
如果需要傳嵌套dict,定義一個(gè)函數(shù)return實(shí)現(xiàn)
users = ['bobby1','bobby2','bobby3','bobby1','bobby2','bobby2']
for user in users:
? ? default_dict[user] +=1
def gen_default():
????return {
????????"name":"",
????????"age":""
????}
default_dict = defaultdict(gen_default)
default_dict['group_01']
# 會返回生成嵌套dict結(jié)構(gòu)
"group1":{
????"name":"",
????"nums":0
}
defaultdict是通過__missing__魔術(shù)方法實(shí)現(xiàn)原理的
????????
查看全部 -
deque是雙端隊(duì)列,可以對兩端進(jìn)行操作。
初始化隊(duì)列:
ulist = deque(("xxx1","xxx2")),參數(shù)接收一個(gè)可迭代對象,
盡量用deque保存相同類型的數(shù)據(jù)
方法:append加到隊(duì)列尾部、appendleft加到隊(duì)列頭部
copy淺拷貝,隊(duì)列里面有不可變元素會直接賦值,可變元素(例如列表)會直接指向原來地址
extend在原來元素上動態(tài)擴(kuò)容,接收可迭代對象
extendleft
insert(索引,元素)
pop、popleft、remove、reverse
應(yīng)用場景:
python3里,from queue import Queue
Queue里面實(shí)際上是通過雙端隊(duì)列完成(put方法調(diào)用是append,get方法調(diào)用的是popleft)
多線程:deque是線程安全的(由GIL保護(hù)的),list非線程安全
查看全部 -
tuple的優(yōu)點(diǎn):
可以作為dict的key,
查看全部 -
*可以接收任意多個(gè)參數(shù)放入一個(gè)tuple中
**可以接收類似于參數(shù)賦值形式的實(shí)參放入dict中
查看全部 -
ChainMap(dict1, dict2)
會跳過相同的鍵
生成迭代器而不是生成新拷貝
new_dict.maps
查看全部 -
python3默認(rèn)dict有序
popitem
move_to_end
查看全部 -
deque雙端隊(duì)列
線程安全
查看全部
舉報(bào)