| Type code | C Type | Python Type | Minimum size in bytes |
| 'b' | signed char | int | 1 |
| 'B' | unsigned char | int | 1 |
| 'u' | wchar_t | Unicode character | 2 |
| 'h' | signed short | int | 2 |
| 'H' | unsigned short | int | 2 |
| 'i' | signed int | int | 2 |
| 'I' | unsigned int | int | 2 |
| 'l' | signed long | int | 4 |
| 'L' | unsigned long | int | 4 |
更詳細的信息可以參考:https://docs.python.org/3.8/library/array.html
C++的map對于新的key會自動使用value type的默認構造函數構造一個值,而Python默認的dict對于不存在的key的訪問會拋出異常(賦值除外)。這是因為Python不知道value的類型,所以沒辦法為我們默認構造。
defaultdict要求我們在構造時指定一個類型,然后會自動根據需要初始化value。這樣我們就可以使用簡單的代碼來實現很多功能。
下面的代碼,我對比了使用defaultdict和original dict實現將學生按照姓的首字母分組的功能,以及分類計數的功能。
import collections
students = ['Zhang San', 'Li Si', 'Zhou liu', 'Chen qi', 'Cheng ba']
# using defaultdict
dd = collections.defaultdict(list)
for s in students:
key = s[0]
dd[key].append(s)
print(dd)
# using original dict (method 1)
od = {}
for s in students:
key = s[0]
if key not in do:
od[key] = []
od[key].append(s)
print(od)
scores = ['A', 'B', 'C', 'A', 'A', 'B', 'C', 'B', 'A', 'A']
# using defaultdict
dd = collections.defaultdict(int)
for s in scores :
dd[s] += 1
print(dd)
# using original dict (method 2)
od = collections.defaultdict(int)
for s in scores :
if s not in do:
do[s] = 1
else:
do[s] += 1
print(od)
編程實踐中我們經常需要創建一些小的數據結構用來整合一組相關聯的數據,簡單的比如地理坐標的經緯度,顏色的RGB值或者矩形框的左上和右下坐標,復雜的比如構造一個窗口的一組參數。
實踐中,我們通常有3中實現方法:
collections的nametuple可以為我們直接構造一個具有名字的簡單類型,方便快捷地實現類似手寫了一個class的效果。
需要注意的是collections.nametuple是一個factory function,它用來幫我們創建一個類型,而不是這個類型的具體對象。創建類型時,我們可以指定各個屬性的名字,之后就可以使用.來訪問了,而且它同時還支持使用下標訪問。同時Named Tuple還支持_asdict函數用來將內部的數值轉換成一個dict。
# class
class Rect:
def __init__(self, x1, y1, x2, y2):
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
def area_class(r):
w = r.x2 - r.x1
h = r.y2 - r.y1
return w*h
r1 = Rect(1,3,5,5)
# __main__.Rect object at 0x7fde252a87f0>
# to show its content, we need to implement __repr__(self) or __str__(self)
print(area_class(r1))
# tuple
def area_tuple(r):
w = r[2]-r[0]
h = r[3]-r[1]
return w*h
r2 = (1,3,5,5)
print(r2)
# (1, 3, 5, 5)
print(area_tuple(r2))
# dict
def area_dict(r):
w = r["x2"] - r["x1"]
h = r["y2"] - r["y1"]
return w*h
r3 = {"x1":1, "y1":3, "x2":5, "y2":5}
print(r3)
# {'x1': 1, 'y1': 3, 'x2': 5, 'y2': 5}
print(area_tuple(r3))
# named tuple
import collections
Rectangle = collections.namedtuple("Rectangle", ["x1", "y1", "x2", "y2"])
def area_namedtuple(r):
w = r.x2 - r.x1
y = r.y2 - r.y1
return w*h
r4 = Rectangle(1,3,5,5)
print(r4)
# Rectangle(x1=1, y1=3, x2=5, y2=5)
x1,y2,x2,y2 = r4
print(x1,y2,x2,y2)
# 1 3 5 5
print(area_namedtuple(r4))
print(area_class(r4)) # work with "." grammar
print(area_tuple(r4)) # work with index
print(area_dict(r4._asdict())) # work with dict
顧名思義,Counter是用來對元素進行計數的,它也是collections這個包里的。根據Python的官方文檔,它是dict類型的一個子類。
在構造的時候輸入一個iterable的類型,比如list,range或是一個mapping的類型,比如dict,defaultdict。然后Counter就會對其中的元素進行計數。
比較特殊的是,Counter對負數沒有做特殊處理,就是說在特殊操作下允許出現測試為負,后面我們會有例子。
c = Counter() # a new, empty counter
c = Counter('gallahad') # a new counter from an iterable
print(c)
# Counter({'a': 3, 'l': 2, 'g': 1, 'h': 1, 'd': 1})
c = Counter({'red': 4, 'blue': 2}) # a new counter from a mapping
print(c)
# Counter({'red': 4, 'blue': 2})
c = Counter(cats=4, dogs=8) # a new counter from keyword args
print(c)
# Counter({'dogs': 8, 'cats': 4})
除了基本的計數功能,它還支持一些常用的相關功能。比如:
c = Counter(a=4, b=2, c=0, d=-2)
sorted(c.elements())
# ['a', 'a', 'a', 'a', 'b', 'b']
Counter('abracadabra').most_common(3)
# [('a', 5), ('b', 2), ('r', 2)]
c1 = Counter(a=4, b=2, d=-2)
c2 = Counter(a=1, b=2, c=3, d=4)
c1.subtract(c2)
c1
# Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
更多的參考信息大家可以參考官方文檔:
https://docs.python.org/3/library/collections.html
以上就是4種非常實用的python內置數據結構的詳細內容,更多關于python內置數據結構的資料請關注腳本之家其它相關文章!
上一篇:Python基礎詳解之描述符
下一篇:Python圖像處理之圖像拼接