當前位置:
首頁 > 知識 > Python 標準庫之 collections 使用教程

Python 標準庫之 collections 使用教程

點擊上方「

Python開發

」,選擇「置頂公眾號」


關鍵時刻,第一時間送達!






引言




Python為我們提供了4種基本的數據結構:list, tuple, dict, set,但是在處理數據量較大的情形的時候,這4種數據結構就明顯過於單一了,比如list作為單向鏈表在某些情形插入的效率會比較低,有時候我們也需要維護一個有序的dict。所以這個時候我們就要用到Python標準庫為我們提供的collections包了,它提供了多個有用的集合類,熟練掌握這些集合類,不僅可以讓我們讓寫出的代碼更加Pythonic,也可以提高我們程序的運行效率。




defaultdict的使用




defaultdict(default_factory)在普通的dict(字典)之上添加了default_factory,使得key(鍵)不存在時會自動生成相應類型的value(值),default_factory參數可以指定成list, set, int等各種合法類型。




example1





>>>

from

collections

import

defaultdict


>>>

s

=

[(

"red"

,

1

),

(

"blue"

,

2

),

(

"red"

,

3

),

(

"blue"

,

4

),

(

"red"

,

1

),

(

"blue"

,

4

)]



我們現在有上面這樣一組list(列表),雖然我們有6組數據,但是仔細觀察後發現其實我們只有兩種color(顏色),但是每一個color對應多個值。現在我們想要將這個list轉換成一個dict(字典),這個dict的key(鍵)對應一種color,dict的value(值)設置為一個list存放color對應的多個值。我們可以使用defaultdict(list)來解決這個問題。





# d可以看作一個dict(字典),dict的value是一個list(列表)


>>>

d

=

defaultdict

(

list

)


>>>

for

k

,

v

in

s

:


...

    

d

[

k

].

append

(

v

)


...


>>>

d


defaultdict

(

<

class

"list"

>

,

{

"blue"

:

[

2

,

4

,

4

],

"red"

:

[

1

,

3

,

1

]})




example2




上面這個例子中有一些不完美的地方,比如說{『blue』: [2, 4, 4], 『red』: [1, 3, 1]}這個defaultdict中blue顏色中包含兩個4,red顏色中包含兩個1,但是我們不希望含有重複的元素,這個時候可以考慮使用defaultdict(set)來解決這個問題。set(集合)相比list(列表)的不同之處在於set中不允許存在相同的元素。





>>>

d

=

defaultdict

(

set

)


>>>

for

k

,

v

in

s

:


...

    

d

[

k

].

add

(

v

)


...


>>>

d


defaultdict

(

<

class

"set"

>

,

{

"blue"

:

{

2

,

4

},

"red"

:

{

1

,

3

}})




example3





>>> s = "hello world"




通過使用defaultdict(int)的形式我們來統計一個字元串中每個字元出現的個數。





>>>

d

=

defaultdict

(

int

)


>>>

for

k

in

s

:


...

    

d

[

k

]

+=

1


...


>>>

d


defaultdict

(

<

class

"int"

>

,

{

"o"

:

2

,

"h"

:

1

,

"w"

:

1

,

"l"

:

3

,

" "

:

1

,

"d"

:

1

,

"e"

:

1

,

"r"

:

1

})




OrderedDict的使用




我們知道默認的dict(字典)是無序的,但是在某些情形我們需要保持dict的有序性,這個時候可以使用OrderedDict,它是dict的一個subclass(子類),但是在dict的基礎上保持了dict的有序型,下面我們來看一下使用方法。




example1





>>>

from

collections

import

OrderedDict


# 無序的dict


>>>

d

=

{

"banana"

:

3

,

"apple"

:

4

,

"pear"

:

1

,

"orange"

:

2

}




這是一個無序的dict(字典),現在我們可以使用OrderedDict來讓這個dict變得有序。





# 將d按照key來排序


>>>

OrderedDict

(

sorted

(

d

.

items

(),

key

=

lambda

t

:

t

[

0

]))


OrderedDict

([(

"apple"

,

4

),

(

"banana"

,

3

),

(

"orange"

,

2

),

(

"pear"

,

1

)])


# 將d按照value來排序


>>>

OrderedDict

(

sorted

(

d

.

items

(),

key

=

lambda

t

:

t

[

1

]))


OrderedDict

([(

"pear"

,

1

),

(

"orange"

,

2

),

(

"banana"

,

3

),

(

"apple"

,

4

)])


# 將d按照key的長度來排序


>>>

OrderedDict

(

sorted

(

d

.

items

(),

key

=

lambda

t

:

len

(

t

[

0

])))


OrderedDict

([(

"pear"

,

1

),

(

"apple"

,

4

),

(

"orange"

,

2

),

(

"banana"

,

3

)])




example2




使用popitem(last=True)方法可以讓我們按照LIFO(先進後出)的順序刪除dict中的key-value,即刪除最後一個插入的鍵值對,如果last=False就按照FIFO(先進先出)刪除dict中key-value。





>>>

d

=

{

"banana"

:

3

,

"apple"

:

4

,

"pear"

:

1

,

"orange"

:

2

}


# 將d按照key來排序


>>>

d

=

OrderedDict

(

sorted

(

d

.

items

(),

key

=

lambda

t

:

t

[

0

]))


>>>

d


OrderedDict

([(

"apple"

,

4

),

(

"banana"

,

3

),

(

"orange"

,

2

),

(

"pear"

,

1

)])


# 使用popitem()方法來移除最後一個key-value對


>>>

d

.

popitem

()


(

"pear"

,

1

)


# 使用popitem(last=False)來移除第一個key-value對


>>>

d

.

popitem

(

last

=

False

)


(

"apple"

,

4

)




example3




使用move_to_end(key, last=True)來改變有序的OrderedDict對象的key-value順序,通過這個方法我們可以將排序好的OrderedDict對象中的任意一個key-value插入到字典的開頭或者結尾。





>>>

d

=

OrderedDict

.

fromkeys

(

"abcde"

)


>>>

d


OrderedDict

([(

"a"

,

None

),

(

"b"

,

None

),

(

"c"

,

None

),

(

"d"

,

None

),

(

"e"

,

None

)])


# 將key為b的key-value對移動到dict的最後


>>>

d

.

move_to_end

(

"b"

)


>>>

d


OrderedDict

([(

"a"

,

None

),

(

"c"

,

None

),

(

"d"

,

None

),

(

"e"

,

None

),

(

"b"

,

None

)])


>>>

""

.

join

(

d

.

keys

())


"acdeb"


# 將key為b的key-value對移動到dict的最前面


>>>

d

.

move_to_end

(

"b"

,

last

=

False

)


>>>

""

.

join

(

d

.

keys

())


"bacde"




deque的使用




list存儲數據的優勢在於按找索引查找元素會很快,但是插入和刪除元素就很慢了,因為它是是單鏈表的數據結構。deque是為了高效實現插入和刪除操作的雙向列表,適合用於隊列和棧,而且線程安全。




list只提供了append和pop方法來從list的尾部插入/刪除元素,但是deque新增了appendleft/popleft允許我們高效的在元素的開頭來插入/刪除元素。而且使用deque在隊列兩端添加(append)或彈出(pop)元素的演算法複雜度大約是O(1),但是對於list對象改變列表長度和數據位置的操作例如 pop(0)和insert(0, v)操作的複雜度高達O(n)。由於對deque的操作和list基本一致,這裡就不重複了。




ChainMap的使用




ChainMap用來將多個dict(字典)組成一個list(只是比喻),可以理解成合併多個字典,但和update不同,而且效率更高。





>>>

from

collections

import

ChainMap


>>>

a

=

{

"a"

:

"A"

,

"c"

:

"C"

}


>>>

b

=

{

"b"

:

"B"

,

"c"

:

"D"

}


>>>

m

=

ChainMap

(

a

,

b

)


# 構造一個ChainMap對象


>>>

m


ChainMap

({

"a"

:

"A"

,

"c"

:

"C"

},

{

"b"

:

"B"

,

"c"

:

"D"

})


>>>

m

[

"a"

]


"A"


>>>

m

[

"b"

]


"B"


# 將m變成一個list


>>>

m

.

maps


[{

"a"

:

"A"

,

"c"

:

"C"

},

{

"b"

:

"B"

,

"c"

:

"D"

}]





# 更新a中的值也會對ChainMap對象造成影響


>>>

a

[

"c"

]

=

"E"


>>>

m

[

"c"

]


"E"


# 從m複製一個ChainMap對象,更新這個複製的對象並不會對m造成影響


>>>

m2

=

m

.

new_child

()


>>>

m2

[

"c"

]

=

"f"


>>>

m

[

"c"

]


"E"


>>>

a

[

"c"

]


"E"


>>>

m2

.

parents


ChainMap

({

"a"

:

"A"

,

"c"

:

"C"

},

{

"b"

:

"B"

,

"c"

:

"D"

})




Counter的使用




example1




Counter也是dict的一個subclass,它是一個無序容器,可以看做一個計數器,用來統計相關元素出現的個數。





>>>

from

collections

import

Counter


>>>

cnt

=

Counter

()


# 統計列表中元素出現的個數


>>>

for

word

in

[

"red"

,

"blue"

,

"red"

,

"green"

,

"blue"

,

"blue"

]

:


...

  

cnt

[

word

]

+=

1


...


>>>

cnt


Counter

({

"blue"

:

3

,

"red"

:

2

,

"green"

:

1

})


# 統計字元串中元素出現的個數


>>>

cnt

=

Counter

()


>>>

for

ch

in

"hello"

:


...

    

cnt

[

ch

]

=

cnt

[

ch

]

+

1


...


>>>

cnt


Counter

({

"l"

:

2

,

"o"

:

1

,

"h"

:

1

,

"e"

:

1

})




example2




使用elements()方法按照元素的出現次數返回一個iterator(迭代器),元素以任意的順序返回,如果元素的計數小於1,將忽略它。





>>>

c

=

Counter

(

a

=

4

,

b

=

2

,

c

=

0

,

d

=-

2

)


>>>

c


Counter

({

"a"

:

4

,

"b"

:

2

,

"c"

:

0

,

"d"

: -

2

})


>>>

c

.

elements

()


<

itertools

.

chain object

at

0x7fb0a069ccf8

>


>>>

next

(

c

)


"a"


# 排序


>>>

sorted

(

c

.

elements

())


[

"a"

,

"a"

,

"a"

,

"a"

,

"b"

,

"b"

]




使用most_common(n)返回一個list, list中包含Counter對象中出現最多前n個元素。





>>>

c

=

Counter

(

"abracadabra"

)


>>>

c


Counter

({

"a"

:

5

,

"b"

:

2

,

"r"

:

2

,

"d"

:

1

,

"c"

:

1

})


>>>

c

.

most_common

(

3

)


[(

"a"

,

5

),

(

"b"

,

2

),

(

"r"

,

2

)]




namedtuple的使用




使用namedtuple(typename, field_names)命名tuple中的元素來使程序更具可讀性。





>>>

from

collections

import

namedtuple


>>>

Point

=

namedtuple

(

"PointExtension"

,

[

"x"

,

"y"

])


>>>

p

=

Point

(

1

,

2

)


>>>

p

.

__class__

.

__name_

_


"PointExtension"


>>>

p

.

x


1


>>>

p

.

y


2






  • 來源:ZiWenXie




  • www.ziwenxie.site/2016/12/10/python-stand-library-collections/



  • Python開發整理髮布,轉載請聯繫作者獲得授權


【點擊成為Java大神】

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發 的精彩文章:

詳解Python爬取房天下的推薦新樓盤
加密貨幣的本質

TAG:Python開發 |