python基礎類型之dict&&set

本文引用至: python基礎類型之dict&sethtml

在python中, 將數據結構分類了兩種,一種是序列(sequence), 另一種是字典(dictionary). 其中,序列也就是咱們前面所說的 list and tuple. 字典就是這裏將要說的兩種-- dict and set
前面介紹了,list && set. 這裏,咱們就來探討一下剩餘兩個datatypespython

dict

dict 打個比方就至關於 js中的對象. 他實際就是一種散列表(hash)的形式. dict 中的內容是無序的, 但每個值都是以key/value形式出現, 因此當咱們須要查找值時, py會直接根據你調用的key來進行索引,最後返回你的值. 他的查找速度是極快的, 複雜度就是O(1)
而相應的損耗就是內存空間, 因此這也符合hash表的特徵, 速度快, 空間大. 經過時間換空間的方式,進行索引.
ok, 如今咱們來建立一個dict:web

>>> my_dict = {1: 'apple', 2: 'ball'}
//key, 咱們也是能夠換的
>>> new_dict = {'name':'jimmy','age':18}
// 訪問只能使用key
>>> new_dict['age']
18

實際上, dict就這麼簡單. 可是, 咱們須要理解他和list的不一樣, 因爲他的feature 是速度快, 空間大,便於查找. 因此這種方式也經常使用於, 數據存儲和傳輸那一塊.
那,有沒有什麼辦法能 convert dict to list呢?
absolutely.
直接使用 list方法便可json

>>> my_dict
{1: 'apple', 2: 'ball'}
>>> list(my_dict)
[1, 2]

不過這樣的現實意義並不大, 由於,實際上,他只會截取你dict中的key 做爲list的value.
可是, list是不能直接轉換爲dict的, 除非你是結合元組進行使用.網絡

>>> my_dict = dict([(1,'apple'), (2,'ball')])
>>> my_dict
{1: 'apple', 2: 'ball'}

最後咱們能夠總結一下就是:
dict 轉化數據結構

dict 中的相關方法

一樣無外乎就是CRUD。 這裏咱們慢慢講.app

dict 添加

這裏很容易理解, 即就是給dict添加新的內容. 不像, list中有關序列的append,extend,insert方法. 在dict中,只提供了setdefault(key[,value]),update([other]) 進行相關的添加操做.less

  • setdefault(key[,value]): 用來向dict中指定添加相應的序列. 若是不存在,則新增. 若是存在 則該次添加默認無效, 而且返回已經存在的值. 實際上,這個方法,真的頗有用. 當咱們須要判斷一個值是否存在,再添加時,就會用到該方法curl

>>> my_dict
{1: 'apple', 2: 'ball'}
>>> my_dict.setdefault(1,[2,3])
'apple'
//若是不存在則默認添加
>>> my_dict.setdefault(3,1)
1
  • update([other]): 該方法是用來批量加入dict。 other的類型能夠爲dict, 也能夠爲tuple+list. 咱們看一下官方給的答案:函數

D.update([E, ]**F) -> None. Update D from dict/iterable E and F.

If E is present and has a .keys() method, then does:  for k in E: D[k] = E[k]
If E is present and lacks a .keys() method, then does:  for k, v in E: D[k] = v
In either case, this is followed by: for k in F:  D[k] = F[k]

上面那段話和keys方法扯上關係了. 實際上,keys是dict的方法. 因此就表明的着dict的類型. 若是你沒有keys 方法, 這裏就至關於使用for...in... 遍歷數據結構,而能這樣遍歷的, 就只有tuple+list. 看個demo:

>>> my_dict.update({1:2,3:4})
// 直接添加dict, 沒問題吧. 繼續
>>> my_dict.update([(5,1)])

就醬. 另外,提醒一點,除了setdefault方法之外的其餘方法,默認都會覆蓋原有的key/value pair.

dict 刪除

這裏dict 提供了大概4種方法: pop,popitem,del, clear. 咱們分開來講一下:

  • pop(k[,d]): 要知道,dict 不一樣於dict 是沒有順序的. 若是你的pop不帶參數, 那就不能怪誰了, please go die. 全部pop的用法就是, 在dict中刪除指定的k, 另外你也能夠帶上,d(就是value). 若是dict中的k不存在的話, 該方法就會返回d, 不然直接返回刪除值.

//指定key刪除
>>> my_dict.pop('age')
27
// 因爲,ket->age已經被刪除了, 這裏咱們使用補充的value做爲備用,以防出錯.
>>> my_dict.pop('age',12)
12 //直接返回實現設好的12
  • popitem(): 這個方法,就不用任何參數了, 他的做用就是,從你的dict中隨便刪除一個pair,並以tuple的形式返回. 但,若是dict已是empty, 那麼就 go die了.

>>> my_dict.popitem()
('name', 'Ranjit')
  • del : del 在這裏 就和list是同樣的了. 用來刪除指定的值.

>>> del my_dict['age']
  • clear(): 不說了, 就是清空的意思

dict 獲取

在list中,咱們獲取部分元素 直接使用分片就行了, 或者大不了使用copy唄. 但在dict中就沒有這麼方便了.
因此, 爲了彌補這個defect, dict提供了幾個比較好的方法.
有: fromkeys(seq[, v]),get(key[,d]),copy(),items(),keys(),values()
莫急,咱們慢慢看

  • fromkeys(seq[, v]): 該方法,實際上就是提取公因式, 用來給不一樣的keys 使用同一個val. 生成一個新的dict. 因此,這也引出了下文會提到的comprehension.

>>> dic = dict.fromkeys([1,2,3],12)
  • get(key[,d]): 相比,直接經過dict[xx]訪問方式而言, 我以爲這個方法,真的沒有什麼用. 比較好的也是他的一個判斷, 當key不存在值,他不會報錯,而且若是你設置好了d,那麼不存在的話,就會返回d.

>>> my_dict.get('name')
'Ranjit'
// 不存在jimmy的key
>>> my_dict.get('jimmy','sexy')
'sexy'
  • copy(): 不說了, 就是所有複製

  • items(): 用來返回,dict_items的類型. 他的形式就至關於tupe+list

>>> my_dict.items()
dict_items([('name', 'Ranjit'), ('address', 'Downtown')])

只是他的類是dict_items

>>> type(my_dict.items())
<class 'dict_items'>
  • keys(): 以dict_keys的形式返回dict中的鍵值.

>>>my_dict.keys()
dict_keys(['name', 'address'])
  • values(): 一樣, 以dict__values的形式,返回value值.

>>> my_dict.values()
dict_values(['Ranjit', 'Downtown'])

最後,說一下最後3種類型, dict_items,dict_keys,dict_values. 到底幹嗎的.
官方解釋是, 這些至關於只是一個快照(view). 並不會持續存在,這樣作的目的就是爲了節省內容. 並且,若是你想將兩個 dict進行比較的時候, 實際上,只要比較他的dict.values,dict.keys 或者, dict.items 是否相同便可. 由於,這樣比較快.(不過,因爲無序,你也能夠直接比較)

>>> dic.items() == my_dict.items()
True

另外,若是你想講keys或者values保留下來,能夠直接使用list方法進行轉義便可.

>>> list(dic.values())
['jimmy', 'Downtown']

dict complement

最後再補充一下關於dict的 周邊方法.

dict comprehension

這個和list類型,用來迅速生成一個dict

>>> squares = {x: x*x for x in range(6)}
>>> squares
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

只要後面是一個能夠遍歷的數據結構就行.
另外, 使用for...in... 遍歷dict, 他的結果是遍歷當中的key 而不是, value.

>>> for x in squares:
...     print(x)

JSON 操做

dict 在python中叫作字典, 而在js中 叫作對象. 將對象字符串化, 就是JSON的實質.
實際上, 這種格式,是很是利於網絡傳輸的. 如今, 大部分web傳輸方式都是使用JSON (JavaScript Object Notation)格式, 而上面的書寫方式, 只須要轉爲json便可。
py 提供了咱們一個json的模塊, 裏面有一些基本方法,最經常使用的,要算dumps和loads.
作個類比:

  • dumps: 至關於js中的JSON.stringify()

  • loads: 至關於js中的JSON.parse()

來具體看看方法參數吧:

  • loads(s, encoding=None[,...]): 實踐上,這是loads提供的參數配置, 通常而言, 咱們只須要默認參數便可. 使用方法很簡單:

>>> json_str
'{"shares": 100, "name": "ACME", "price": 542.23}'
>>> json.loads(json_str)
{'name': 'ACME', 'shares': 100, 'price': 542.23}

對比一下,引號應該就知道其中的意義了.

  • dumps(obj[,..]): 一樣,dumps 咱們使用默認參數便可. 用來將obj 轉化爲str.

>>> data
{'shares': 100, 'name': 'ACME', 'price': 542.23}
>>> json.dumps(data)
'{"shares": 100, "name": "ACME", "price": 542.23}'

一樣,你們比較一下就知道了.
另外, 這裏須要說起幾點的是: 在和JSON相互轉化的過程當中, FalseTrue converted to false/true. None -> null. 另外json 中還提供了 load,dump方法,用來對文件進行操做. 有興趣的同窗,能夠參考一下官方文檔: json

來看張總結圖譜吧
py dict相關方法

Set 剖析

這裏,想要介紹一個, 專門爲數學運算準備的數據結構--set. set不一樣於dict, 他沒有成對的key/value。 他只會包含,不重複的value. 一個簡單的set,咱們能夠這麼寫

>>> s = {1,2,3,4}
// 若是你要建立空的set的話, 請使用set()方法.
>>> s = set()
// 否則的話, 就是dict類型了

就是講你所須要的值放在 curly braces裏面便可.
咱們來看看他最重要的feature--不重複

>>> s = {x for x in [1,1,1,1]}
>>> s
{1}

另外, set是不能包含mutable datatype. 好比 list。(tuple 能夠)

>>> s = {[1,2,3]}
TypeError: unhashable type: 'list'
// 已經給出, 不能存放非 hash 值

實際上, set還有一個很重要的做用,就是用來 remove duplicates. 特別針對於list
使用方法就是直接使用set()進行過濾便可. 咱們能夠定義一個函數unique

def unique(l):
    l = set(l)
    l = list(l)
    return l

>>> unique([1,1,1])
[1]

那麼,咱們怎麼訪問set呢?
孩紙, 對不起,
一樣, set和dict類型, 也存在CRUD操做, 不過,他還自帶了innate buffer. 集合運算

set method

create 相關

py提供了兩個方法, 一個是add, 一個是update.

  • add(ele): 該方法,用來添加一個ele. 但若是該ele存在, 那麼該次添加就是useless

>>> new_set
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> new_set.add(10)
  • update(iterable): 該方法用來添加多個set元素. 參數必須是能夠遍歷的.好比,list,set,tuple,dict. 固然,若是是dict的話, 他只會添加key進去

>>> new_set.update({'a':1,'b':2})
{'a','b'}

delete 相關

在set中, 一樣提供了幾個可供處理的方法: discard,remove,pop,clear.
discard(ele)和remove(ele) 其實是有點相像的. 惟一的difference是, 使用discard時, 若是元素不存在,不會報錯,而remove會.

>>> my_set
{1, 3, 5}
>>> my_set.discard(2)
>>> my_set
{1, 3, 5}
>>> my_set.remove(2)
KeyError: 2

那set不是無序的嗎? 爲何會有pop這個方法呢?
對比與dict 中的popitem方法而言, 在set中,pop就已經能夠表明這個意思了. 即, 使用pop()方法,會隨機刪除 set中的某一個值.而且會返回刪除的值. 若是爲空的話,會報錯

>>> new_set
{0, 1, 2}
>>> new_set.pop()
0

clear就是清空的意思,就醬.
對於list有tuple, 而set 對應的immutable datatype就是 frozenset. frozenset實際上就是 固定的set. 因此, 對於create 和 delete 方法而言是不能應用在frozenset上的. 那frozenset該怎麼玩呢?

frozenset

定義一個frozenset, 能夠直接使用frozenset() 方法.

  • frozenset(iterable): 它裏面接受能夠進行遍歷的datatype, 上面所說的 set,list等都行

>>> A = frozenset([1, 2, 3, 4])
>>> A
frozenset({1, 2, 3, 4})

那咱們何時會使用到呢?
表問我, 我也母雞. 看心情吧

接下來,才應該是set的重頭戲, 集合操做.

set 集合操做

簡單的結合操做無外乎: 交(&),並(|),差(-),對稱差(^). 簡單的還有包含(⊆),真包含(⊂).
咱們先來看幾個容易理解的:

set Union

兩個集合相併:
union

在python中, 咱們可使用| operator。 或者是union()方法

>>> A | B
{1, 2, 3}
>>> A.union(B)
//等價於
>>> B.union(A)

還記得, 並的對稱性吧. A|B = B|A

set intersection

兩個集合相交:
intersection

在python中, 咱們就可使用 & 表達式, 或者 intersection方法,來作.

>>> A & B
{4, 5}
>>> A.intersection(B)
{4, 5}
>>> B.intersection(A)
{4, 5}

set Difference

兩個集合的差集:
difference
在python中, 咱們就可使用- 或者difference()方法來表示

>>> A - B
{1, 2, 3}
>>> A.difference(B)
{1, 2, 3}

這個就是上圖的表達式

set Symmetric Difference

兩個集合的對稱差 [(A-B)∪(B-A)]:
symmetric
在python中,表達可使用^ 或者symmetric_difference()方法.(你以爲那個簡單?)

>>> A ^ B
{1, 2, 3, 6}
>>> A.symmetric_difference(B)

上面兩個就是兩個集合的基本操做. 而且衍生出另一個set. 在python的set操做中, 還有判斷兩個集合是否相關的方法: isdisjoint(),issubset(),issuperset().
如今假設有集合A和集合B。

>>> B
{0, 1, 2, 3}
>>> A
{0, 1, 2}
  • isdisjoint(): 判斷兩集合是否相交. 記住, 包含並非相交, 相交是指有一部分包括,有一部分不包括, 至關於就是兩個圓外邊界相交

>>> A.isdisjoint(B)  //兩個的關係是包含的意思
False
>>> A.issubset(B)
True
  • A.issubset(B): 判斷集合B是否包含集合A. 固然, 徹底相等也算包含. 實際上就是數學中的⊆.

  • A.issuperset(B): 判斷集合A是否包含集合B。 這裏我就不繞了, 你們看狀況使用便可.

>>> A.issubset(B)
True
>>> A.issuperset(B)
False

另外, 咱們檢查一個元素是否在另一個set中,能夠直接使用 in關鍵字了.
看個demo.

>>> A
{0, 1, 2, 3}
>>> 1 in A
True

到這裏, set的基本內容,應該差很少了. 剩下的就是在實踐中,不斷磨練了.
看個總結圖:

set 方法

相關文章
相關標籤/搜索