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