collection模块是对Python的通用内置容器:字典
、列表、元组和集合的扩展,它包含一些专业的容器数据类型:
- Counter(计数器):dict子类,用于计算可哈希性对象的个数。
- OrderedDict(有序字典):dict 子类,记录着数据成员添加的顺序。
- defaultdict(默认字典):dict 子类,调用一个工厂函数来为dict的values值缺失提供一个默认值。
- namedtuple(可命名元组):工厂函数生成有命名字段的tuple子类。
- deque(双向队列):能在“队列”两端快速出队、入队的函数,类似于队列的(list-like)的容器。
- ChainMap:为多个映射创建单一视图的类字典类型。
UserDict:
将字典包裹起来使得创建字典的子类更容易。UserList
:将列表对象包裹起来使得创建列表的子类更容易。UserString
:将字符串对象包裹起来使得创建字符串的子类更容易。
参考网页:https://docs.python.org/3.5/library/collections.html
1.计数器(counter)
Counter
是dict
的子类,用于计数可哈希性对象。它是一个无序的容器,元素存储为字典键,计数值存储为字典值。计数允许任何整数值,包括零或负计数。Counter
类相似于bags或multisets等语言类。
它的元素从一个可迭代对象计数,或从另一个映射(或计数器)初始化。
1 class Counter(dict): 2 '''Dict subclass for counting hashable items. Sometimes called a bag 3 or multiset. Elements are stored as dictionary keys and their counts 4 are stored as dictionary values. 5 6 >>> c = Counter('abcdeabcdabcaba') # count elements from a string 7 8 >>> c.most_common(3) # three most common elements 9 [('a', 5), ('b', 4), ('c', 3)] 10 >>> sorted(c) # list all unique elements 11 ['a', 'b', 'c', 'd', 'e'] 12 >>> ''.join(sorted(c.elements())) # list elements with repetitions 13 'aaaaabbbbcccdde' 14 >>> sum(c.values()) # total of all counts 15 15 16 17 >>> c['a'] # count of letter 'a' 18 5 19 >>> for elem in 'shazam': # update counts from an iterable 20 ... c[elem] += 1 # by adding 1 to each element's count 21 >>> c['a'] # now there are seven 'a' 22 7 23 >>> del c['b'] # remove all 'b' 24 >>> c['b'] # now there are zero 'b' 25 0 26 27 >>> d = Counter('simsalabim') # make another counter 28 >>> c.update(d) # add in the second counter 29 >>> c['a'] # now there are nine 'a' 30 9 31 32 >>> c.clear() # empty the counter 33 >>> c 34 Counter() 35 36 Note: If a count is set to zero or reduced to zero, it will remain 37 in the counter until the entry is deleted or the counter is cleared: 38 39 >>> c = Counter('aaabbc') 40 >>> c['b'] -= 2 # reduce the count of 'b' by two 41 >>> c.most_common() # 'b' is still in, but its count is zero 42 [('a', 3), ('c', 1), ('b', 0)] 43 44 ''' 45 # References: 46 # http://en.wikipedia.org/wiki/Multiset 47 # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html 48 # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm 49 # http://code.activestate.com/recipes/259174/ 50 # Knuth, TAOCP Vol. II section 4.6.3 51 52 def __init__(*args, **kwds): 53 '''Create a new, empty Counter object. And if given, count elements 54 from an input iterable. Or, initialize the count from another mapping 55 of elements to their counts. 56 57 >>> c = Counter() # a new, empty counter 58 >>> c = Counter('gallahad') # a new counter from an iterable 59 >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping 60 >>> c = Counter(a=4, b=2) # a new counter from keyword args 61 62 ''' 63 if not args: 64 raise TypeError("descriptor '__init__' of 'Counter' object " 65 "needs an argument") 66 self, *args = args 67 if len(args) > 1: 68 raise TypeError('expected at most 1 arguments, got %d' % len(args)) 69 super(Counter, self).__init__() 70 self.update(*args, **kwds) 71 72 def __missing__(self, key): 73 'The count of elements not in the Counter is zero.' 74 # Needed so that self[missing_item] does not raise KeyError 75 return 0 76 77 def most_common(self, n=None): 78 '''List the n most common elements and their counts from the most 79 common to the least. If n is None, then list all element counts. 80 81 >>> Counter('abcdeabcdabcaba').most_common(3) 82 [('a', 5), ('b', 4), ('c', 3)] 83 84 ''' 85 # Emulate Bag.sortedByCount from Smalltalk 86 if n is None: 87 return sorted(self.items(), key=_itemgetter(1), reverse=True) 88 return _heapq.nlargest(n, self.items(), key=_itemgetter(1)) 89 90 def elements(self): 91 '''Iterator over elements repeating each as many times as its count. 92 93 >>> c = Counter('ABCABC') 94 >>> sorted(c.elements()) 95 ['A', 'A', 'B', 'B', 'C', 'C'] 96 97 # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1 98 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) 99 >>> product = 1 100 >>> for factor in prime_factors.elements(): # loop over factors 101 ... product *= factor # and multiply them 102 >>> product 103 1836 104 105 Note, if an element's count has been set to zero or is a negative 106 number, elements() will ignore it. 107 108 ''' 109 # Emulate Bag.do from Smalltalk and Multiset.begin from C++. 110 return _chain.from_iterable(_starmap(_repeat, self.items())) 111 112 # Override dict methods where necessary 113 114 @classmethod 115 def fromkeys(cls, iterable, v=None): 116 # There is no equivalent method for counters because setting v=1 117 # means that no element can have a count greater than one. 118 raise NotImplementedError( 119 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') 120 121 def update(*args, **kwds): 122 '''Like dict.update() but add counts instead of replacing them. 123 124 Source can be an iterable, a dictionary, or another Counter instance. 125 126 >>> c = Counter('which') 127 >>> c.update('witch') # add elements from another iterable 128 >>> d = Counter('watch') 129 >>> c.update(d) # add elements from another counter 130 >>> c['h'] # four 'h' in which, witch, and watch 131 4 132 133 ''' 134 # The regular dict.update() operation makes no sense here because the 135 # replace behavior results in the some of original untouched counts 136 # being mixed-in with all of the other counts for a mismash that 137 # doesn't have a straight-forward interpretation in most counting 138 # contexts. Instead, we implement straight-addition. Both the inputs 139 # and outputs are allowed to contain zero and negative counts. 140 141 if not args: 142 raise TypeError("descriptor 'update' of 'Counter' object " 143 "needs an argument") 144 self, *args = args 145 if len(args) > 1: 146 raise TypeError('expected at most 1 arguments, got %d' % len(args)) 147 iterable = args[0] if args else None 148 if iterable is not None: 149 if isinstance(iterable, Mapping): 150 if self: 151 self_get = self.get 152 for elem, count in iterable.items(): 153 self[elem] = count + self_get(elem, 0) 154 else: 155 super(Counter, self).update(iterable) # fast path when counter is empty 156 else: 157 _count_elements(self, iterable) 158 if kwds: 159 self.update(kwds) 160 161 def subtract(*args, **kwds): 162 '''Like dict.update() but subtracts counts instead of replacing them. 163 Counts can be reduced below zero. Both the inputs and outputs are 164 allowed to contain zero and negative counts. 165 166 Source can be an iterable, a dictionary, or another Counter instance. 167 168 >>> c = Counter('which') 169 >>> c.subtract('witch') # subtract elements from another iterable 170 >>> c.subtract(Counter('watch')) # subtract elements from another counter 171 >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch 172 0 173 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch 174 -1 175 176 ''' 177 if not args: 178 raise TypeError("descriptor 'subtract' of 'Counter' object " 179 "needs an argument") 180 self, *args = args 181 if len(args) > 1: 182 raise TypeError('expected at most 1 arguments, got %d' % len(args)) 183 iterable = args[0] if args else None 184 if iterable is not None: 185 self_get = self.get 186 if isinstance(iterable, Mapping): 187 for elem, count in iterable.items(): 188 self[elem] = self_get(elem, 0) - count 189 else: 190 for elem in iterable: 191 self[elem] = self_get(elem, 0) - 1 192 if kwds: 193 self.subtract(kwds) 194 195 def copy(self): 196 'Return a shallow copy.' 197 return self.__class__(self) 198 199 def __reduce__(self): 200 return self.__class__, (dict(self),) 201 202 def __delitem__(self, elem): 203 'Like dict.__delitem__() but does not raise KeyError for missing values.' 204 if elem in self: 205 super().__delitem__(elem) 206 207 def __repr__(self): 208 if not self: 209 return '%s()' % self.__class__.__name__ 210 try: 211 items = ', '.join(map('%r: %r'.__mod__, self.most_common())) 212 return '%s({%s})' % (self.__class__.__name__, items) 213 except TypeError: 214 # handle case where values are not orderable 215 return '{0}({1!r})'.format(self.__class__.__name__, dict(self)) 216 217 # Multiset-style mathematical operations discussed in: 218 # Knuth TAOCP Volume II section 4.6.3 exercise 19 219 # and at http://en.wikipedia.org/wiki/Multiset 220 # 221 # Outputs guaranteed to only include positive counts. 222 # 223 # To strip negative and zero counts, add-in an empty counter: 224 # c += Counter() 225 226 def __add__(self, other): 227 '''Add counts from two counters. 228 229 >>> Counter('abbb') + Counter('bcc') 230 Counter({'b': 4, 'c': 2, 'a': 1}) 231 232 ''' 233 if not isinstance(other, Counter): 234 return NotImplemented 235 result = Counter() 236 for elem, count in self.items(): 237 newcount = count + other[elem] 238 if newcount > 0: 239 result[elem] = newcount 240 for elem, count in other.items(): 241 if elem not in self and count > 0: 242 result[elem] = count 243 return result 244 245 def __sub__(self, other): 246 ''' Subtract count, but keep only results with positive counts. 247 248 >>> Counter('abbbc') - Counter('bccd') 249 Counter({'b': 2, 'a': 1}) 250 251 ''' 252 if not isinstance(other, Counter): 253 return NotImplemented 254 result = Counter() 255 for elem, count in self.items(): 256 newcount = count - other[elem] 257 if newcount > 0: 258 result[elem] = newcount 259 for elem, count in other.items(): 260 if elem not in self and count < 0: 261 result[elem] = 0 - count 262 return result 263 264 def __or__(self, other): 265 '''Union is the maximum of value in either of the input counters. 266 267 >>> Counter('abbb') | Counter('bcc') 268 Counter({'b': 3, 'c': 2, 'a': 1}) 269 270 ''' 271 if not isinstance(other, Counter): 272 return NotImplemented 273 result = Counter() 274 for elem, count in self.items(): 275 other_count = other[elem] 276 newcount = other_count if count < other_count else count 277 if newcount > 0: 278 result[elem] = newcount 279 for elem, count in other.items(): 280 if elem not in self and count > 0: 281 result[elem] = count 282 return result 283 284 def __and__(self, other): 285 ''' Intersection is the minimum of corresponding counts. 286 287 >>> Counter('abbb') & Counter('bcc') 288 Counter({'b': 1}) 289 290 ''' 291 if not isinstance(other, Counter): 292 return NotImplemented 293 result = Counter() 294 for elem, count in self.items(): 295 other_count = other[elem] 296 newcount = count if count < other_count else other_count 297 if newcount > 0: 298 result[elem] = newcount 299 return result 300 301 def __pos__(self): 302 'Adds an empty counter, effectively stripping negative and zero counts' 303 result = Counter() 304 for elem, count in self.items(): 305 if count > 0: 306 result[elem] = count 307 return result 308 309 def __neg__(self): 310 '''Subtracts from an empty counter. Strips positive and zero counts, 311 and flips the sign on negative counts. 312 313 ''' 314 result = Counter() 315 for elem, count in self.items(): 316 if count < 0: 317 result[elem] = 0 - count 318 return result 319 320 def _keep_positive(self): 321 '''Internal method to strip elements with a negative or zero count''' 322 nonpositive = [elem for elem, count in self.items() if not count > 0] 323 for elem in nonpositive: 324 del self[elem] 325 return self 326 327 def __iadd__(self, other): 328 '''Inplace add from another counter, keeping only positive counts. 329 330 >>> c = Counter('abbb') 331 >>> c += Counter('bcc') 332 >>> c 333 Counter({'b': 4, 'c': 2, 'a': 1}) 334 335 ''' 336 for elem, count in other.items(): 337 self[elem] += count 338 return self._keep_positive() 339 340 def __isub__(self, other): 341 '''Inplace subtract counter, but keep only results with positive counts. 342 343 >>> c = Counter('abbbc') 344 >>> c -= Counter('bccd') 345 >>> c 346 Counter({'b': 2, 'a': 1}) 347 348 ''' 349 for elem, count in other.items(): 350 self[elem] -= count 351 return self._keep_positive() 352 353 def __ior__(self, other): 354 '''Inplace union is the maximum of value from either counter. 355 356 >>> c = Counter('abbb') 357 >>> c |= Counter('bcc') 358 >>> c 359 Counter({'b': 3, 'c': 2, 'a': 1}) 360 361 ''' 362 for elem, other_count in other.items(): 363 count = self[elem] 364 if other_count > count: 365 self[elem] = other_count 366 return self._keep_positive() 367 368 def __iand__(self, other): 369 '''Inplace intersection is the minimum of corresponding counts. 370 371 >>> c = Counter('abbb') 372 >>> c &= Counter('bcc') 373 >>> c 374 Counter({'b': 1}) 375 376 ''' 377 for elem, count in self.items(): 378 other_count = other[elem] 379 if other_count < count: 380 self[elem] = other_count 381 return self._keep_positive()
1)计数器的创建
from collections import Counter #Counter 需要申明 a=Counter() # 创建空计数器 b=Counter('aabbbcccc') # 可迭代对象计数的方式创建对象 c = Counter({'red': 4, 'blue': 2}) # 映射方法创建计数器 d = Counter(cats=4, dogs=8) # 键值的方法创建计数器
2)计数器元素的删除
1 a=Counter({'a':2,'b':6,'c':4,'d':0,'e':-2}) 2 print(a) 3 a['a']=0 #修改了计数器元素里的值 4 print(a) 5 del a['b'] #删除了元素 6 print(a) 7 8 #运行结果 9 Counter({'b': 6, 'c': 4, 'a': 2, 'd': 0, 'e': -2}) 10 Counter({'b': 6, 'c': 4, 'a': 0, 'd': 0, 'e': -2}) 11 Counter({'c': 4, 'a': 0, 'd': 0, 'e': -2})
3)计数器的部分功能属性
most_common(self, n=None):
把计数器转化成列表,元素转化成元组,返回n个最常见的元素及其计数的列表,从最常见到最少见。如果省略n或为None
,most_common()
返回计数器中所有元素。具有相等计数的元素是任意排序的。
1 a=Counter({'a':2,'b':6,'c':4,'d':0,'e':-2}) 2 b=a.most_common() 3 c=a.most_common(2) 4 print(a) 5 print(b,type(b)) 6 print(c,type(c)) 7 8 #运行结果 9 Counter({'b': 6, 'c': 4, 'a': 2, 'd': 0, 'e': -2}) 10 [('b', 6), ('c', 4), ('a', 2), ('d', 0), ('e', -2)] <class 'list'> 11 [('b', 6), ('c', 4)] <class 'list'>
elements(self):
返回一个迭代器,对元素重复迭代其计数次。元素以随机顺序返回。如果元素的计数小于1,elements()
将忽略它。
1 a=Counter({'a':2,'b':6,'c':4,'d':0,'e':-2}) 2 b=a.elements() 3 c=sorted(a.elements()) 4 print(a) 5 print(b,type(b)) 6 print(c,type(c)) 7 8 #运行结果 9 Counter({'b': 6, 'c': 4, 'a': 2, 'd': 0, 'e': -2}) 10 <itertools.chain object at 0x00225A50> <class 'itertools.chain'> 11 ['a', 'a', 'b', 'b', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c'] <class 'list'>
update(*args, **kwds):
元素从一个可迭代对象计数或从另一个映射(或计数器)增加。类似dict.update()
,但增加计数,而不是替换它们。此外,可迭代对象应为一系列元素,而不是(key, value)
对。
1 a=Counter({'a':2,'b':6,'c':4,'d':0,'e':-2}) 2 a.update('abe') 3 a.update({'g':1}) 4 print(a) 5 6 #运行结果 7 Counter({'b': 7, 'c': 4, 'a': 3, 'g': 1, 'd': 0, 'e': -1})
subtract(*args, **kwds):
从一个可迭代对象或另一个映射(或计数器)中减去元素。类似dict.update()
,但减去计数,而不是替换它们。输入和输出都可以为零或负。
1 a=Counter({'a':2,'b':6,'c':4,'d':0,'e':-2}) 2 a.subtract('ade') 3 print(a) 4 5 #运行结果 6 Counter({'b': 6, 'c': 4, 'a': 1, 'd': -1, 'e': -3})
2.有序字典(OrderedDict )
有序字典与常规字典类似,但它们记住键值对插入的顺序。当对有序字典进行迭代时,项目按它们的键首次添加的顺序返回。
1 class OrderedDict(dict): 2 'Dictionary that remembers insertion order' 3 # An inherited dict maps keys to values. 4 # The inherited dict provides __getitem__, __len__, __contains__, and get. 5 # The remaining methods are order-aware. 6 # Big-O running times for all methods are the same as regular dictionaries. 7 8 # The internal self.__map dict maps keys to links in a doubly linked list. 9 # The circular doubly linked list starts and ends with a sentinel element. 10 # The sentinel element never gets deleted (this simplifies the algorithm). 11 # The sentinel is in self.__hardroot with a weakref proxy in self.__root. 12 # The prev links are weakref proxies (to prevent circular references). 13 # Individual links are kept alive by the hard reference in self.__map. 14 # Those hard references disappear when a key is deleted from an OrderedDict. 15 16 def __init__(*args, **kwds): 17 '''Initialize an ordered dictionary. The signature is the same as 18 regular dictionaries, but keyword arguments are not recommended because 19 their insertion order is arbitrary. 20 21 ''' 22 if not args: 23 raise TypeError("descriptor '__init__' of 'OrderedDict' object " 24 "needs an argument") 25 self, *args = args 26 if len(args) > 1: 27 raise TypeError('expected at most 1 arguments, got %d' % len(args)) 28 try: 29 self.__root 30 except AttributeError: 31 self.__hardroot = _Link() 32 self.__root = root = _proxy(self.__hardroot) 33 root.prev = root.next = root 34 self.__map = {} 35 self.__update(*args, **kwds) 36 37 def __setitem__(self, key, value, 38 dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link): 39 'od.__setitem__(i, y) <==> od[i]=y' 40 # Setting a new item creates a new link at the end of the linked list, 41 # and the inherited dictionary is updated with the new key/value pair. 42 if key not in self: 43 self.__map[key] = link = Link() 44 root = self.__root 45 last = root.prev 46 link.prev, link.next, link.key = last, root, key 47 last.next = link 48 root.prev = proxy(link) 49 dict_setitem(self, key, value) 50 51 def __delitem__(self, key, dict_delitem=dict.__delitem__): 52 'od.__delitem__(y) <==> del od[y]' 53 # Deleting an existing item uses self.__map to find the link which gets 54 # removed by updating the links in the predecessor and successor nodes. 55 dict_delitem(self, key) 56 link = self.__map.pop(key) 57 link_prev = link.prev 58 link_next = link.next 59 link_prev.next = link_next 60 link_next.prev = link_prev 61 link.prev = None 62 link.next = None 63 64 def __iter__(self): 65 'od.__iter__() <==> iter(od)' 66 # Traverse the linked list in order. 67 root = self.__root 68 curr = root.next 69 while curr is not root: 70 yield curr.key 71 curr = curr.next 72 73 def __reversed__(self): 74 'od.__reversed__() <==> reversed(od)' 75 # Traverse the linked list in reverse order. 76 root = self.__root 77 curr = root.prev 78 while curr is not root: 79 yield curr.key 80 curr = curr.prev 81 82 def clear(self): 83 'od.clear() -> None. Remove all items from od.' 84 root = self.__root 85 root.prev = root.next = root 86 self.__map.clear() 87 dict.clear(self) 88 89 def popitem(self, last=True): 90 '''od.popitem() -> (k, v), return and remove a (key, value) pair. 91 Pairs are returned in LIFO order if last is true or FIFO order if false. 92 93 ''' 94 if not self: 95 raise KeyError('dictionary is empty') 96 root = self.__root 97 if last: 98 link = root.prev 99 link_prev = link.prev 100 link_prev.next = root 101 root.prev = link_prev 102 else: 103 link = root.next 104 link_next = link.next 105 root.next = link_next 106 link_next.prev = root 107 key = link.key 108 del self.__map[key] 109 value = dict.pop(self, key) 110 return key, value 111 112 def move_to_end(self, key, last=True): 113 '''Move an existing element to the end (or beginning if last==False). 114 115 Raises KeyError if the element does not exist. 116 When last=True, acts like a fast version of self[key]=self.pop(key). 117 118 ''' 119 link = self.__map[key] 120 link_prev = link.prev 121 link_next = link.next 122 link_prev.next = link_next 123 link_next.prev = link_prev 124 root = self.__root 125 if last: 126 last = root.prev 127 link.prev = last 128 link.next = root 129 last.next = root.prev = link 130 else: 131 first = root.next 132 link.prev = root 133 link.next = first 134 root.next = first.prev = link 135 136 def __sizeof__(self): 137 sizeof = _sys.getsizeof 138 n = len(self) + 1 # number of links including root 139 size = sizeof(self.__dict__) # instance dictionary 140 size += sizeof(self.__map) * 2 # internal dict and inherited dict 141 size += sizeof(self.__hardroot) * n # link objects 142 size += sizeof(self.__root) * n # proxy objects 143 return size 144 145 update = __update = MutableMapping.update 146 147 def keys(self): 148 "D.keys() -> a set-like object providing a view on D's keys" 149 return _OrderedDictKeysView(self) 150 151 def items(self): 152 "D.items() -> a set-like object providing a view on D's items" 153 return _OrderedDictItemsView(self) 154 155 def values(self): 156 "D.values() -> an object providing a view on D's values" 157 return _OrderedDictValuesView(self) 158 159 __ne__ = MutableMapping.__ne__ 160 161 __marker = object() 162 163 def pop(self, key, default=__marker): 164 '''od.pop(k[,d]) -> v, remove specified key and return the corresponding 165 value. If key is not found, d is returned if given, otherwise KeyError 166 is raised. 167 168 ''' 169 if key in self: 170 result = self[key] 171 del self[key] 172 return result 173 if default is self.__marker: 174 raise KeyError(key) 175 return default 176 177 def setdefault(self, key, default=None): 178 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' 179 if key in self: 180 return self[key] 181 self[key] = default 182 return default 183 184 @_recursive_repr() 185 def __repr__(self): 186 'od.__repr__() <==> repr(od)' 187 if not self: 188 return '%s()' % (self.__class__.__name__,) 189 return '%s(%r)' % (self.__class__.__name__, list(self.items())) 190 191 def __reduce__(self): 192 'Return state information for pickling' 193 inst_dict = vars(self).copy() 194 for k in vars(OrderedDict()): 195 inst_dict.pop(k, None) 196 return self.__class__, (), inst_dict or None, None, iter(self.items()) 197 198 def copy(self): 199 'od.copy() -> a shallow copy of od' 200 return self.__class__(self) 201 202 @classmethod 203 def fromkeys(cls, iterable, value=None): 204 '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S. 205 If not specified, the value defaults to None. 206 207 ''' 208 self = cls() 209 for key in iterable: 210 self[key] = value 211 return self 212 213 def __eq__(self, other): 214 '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive 215 while comparison to a regular mapping is order-insensitive. 216 217 ''' 218 if isinstance(other, OrderedDict): 219 return dict.__eq__(self, other) and all(map(_eq, self, other)) 220 return dict.__eq__(self, other) 221 222 223 try: 224 from _collections import OrderedDict 225 except ImportError: 226 # Leave the pure Python version in place. 227 pass
1)有序字典的创建:
1 from collections import OrderedDict 2 3 a=dict() # 4 b=OrderedDict() 5 a['a']=1 6 a['b']=2 7 a['c']=3 8 a['d']=4 9 b['a']=1 10 b['b']=2 11 b['c']=3 12 b['d']=4 13 print(a,type(a)) 14 print(b,type(b)) 15 16 #运行结果 17 {'a': 1, 'c': 3, 'd': 4, 'b': 2} <class 'dict'> 18 OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)]) <class 'collections.OrderedDict'>
2)有序字典的功能:
有序字典继承了字典的功能,下面只介绍与字典不同功能。
popitem(self, last=True):
返回并删除字典中的键值对。如果last为True(默认值),则以LIFO顺序返回这些键值对,如果为False,则以FIFO顺序返回。
1 a=OrderedDict() 2 a['a']=1 3 a['b']=2 4 a['c']=3 5 a['d']=4 6 b=a.popitem() 7 print(a) 8 print(b) 9 10 #运行结果 11 OrderedDict([('a', 1), ('b', 2), ('c', 3)]) 12 ('d', 4)
move_to_end(self, key, last=True):
将一个已存在key移动到有序字典的另一端。如果last为True(默认值),则项目移动到末尾,如果last为False,则移动到开始。如果key不存在,引发KeyError。
1 a=OrderedDict() 2 a['a']=1 3 a['b']=2 4 a['c']=3 5 a['d']=4 6 print(a) 7 b=a.move_to_end('b') 8 print(a) 9 10 #运行结果 11 OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4)]) 12 OrderedDict([('a', 1), ('c', 3), ('d', 4), ('b', 2)])
3.默认字典(defaultdict)
defaultdict可以把字典指定一个默认value,可以是字典/列表等。返回一个新的类似字典的对象,功能与dict类相同。
如:
1 from collections import defaultdict 2 3 a=defaultdict(list) #默认value为list 4 b=defaultdict(tuple) #默认value为tuple 5 c=defaultdict(dict) #默认value为dict 6 d=dict() 7 print(a) 8 print(b) 9 print(c) 10 print(d) 11 12 #运行结果 13 defaultdict(<class 'list'>, {}) 14 defaultdict(<class 'tuple'>, {}) 15 defaultdict(<class 'dict'>, {}) 16 {}
应用:
1 s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)] 2 d = defaultdict(list) 3 for k, v in s: 4 d[k].append(v) #如果使用普通字典,需要先给字典初始化键值对 5 c=sorted(d.items()) 6 print(type(s)) 7 print(d) 8 print(c,type(c)) 9 10 #运行结果 11 <class 'list'> 12 defaultdict(<class 'list'>, {'red': [1], 'blue': [2, 4], 'yellow': [1, 3]}) 13 [('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])] <class 'list'>
默认字典的功能:
1 class defaultdict(dict): 2 """ 3 defaultdict(default_factory[, ...]) --> dict with default factory 4 5 The default factory is called without arguments to produce 6 a new value when a key is not present, in __getitem__ only. 7 A defaultdict compares equal to a dict with the same items. 8 All remaining arguments are treated the same as if they were 9 passed to the dict constructor, including keyword arguments. 10 """ 11 def copy(self): # real signature unknown; restored from __doc__ 12 """ D.copy() -> a shallow copy of D. """ 13 pass 14 15 def __copy__(self, *args, **kwargs): # real signature unknown 16 """ D.copy() -> a shallow copy of D. """ 17 pass 18 19 def __getattribute__(self, *args, **kwargs): # real signature unknown 20 """ Return getattr(self, name). """ 21 pass 22 23 def __init__(self, default_factory=None, **kwargs): # known case of _collections.defaultdict.__init__ 24 """ 25 defaultdict(default_factory[, ...]) --> dict with default factory 26 27 The default factory is called without arguments to produce 28 a new value when a key is not present, in __getitem__ only. 29 A defaultdict compares equal to a dict with the same items. 30 All remaining arguments are treated the same as if they were 31 passed to the dict constructor, including keyword arguments. 32 33 # (copied from class doc) 34 """ 35 pass 36 37 def __missing__(self, key): # real signature unknown; restored from __doc__ 38 """ 39 __missing__(key) # Called by __getitem__ for missing key; pseudo-code: 40 if self.default_factory is None: raise KeyError((key,)) 41 self[key] = value = self.default_factory() 42 return value 43 """ 44 pass 45 46 def __reduce__(self, *args, **kwargs): # real signature unknown 47 """ Return state information for pickling. """ 48 pass 49 50 def __repr__(self, *args, **kwargs): # real signature unknown 51 """ Return repr(self). """ 52 pass 53 54 default_factory = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 55 """Factory for default value called by __missing__()."""
4.可命名元组(namedtuple)
1)可命名元组的说明
给元组中每个位置上的元素命名,它们可以使用常规的元组方法,可以让访问元素可以按名称而不是按位置索引。
collections.namedtuple
(typename, field_names, verbose=False, rename=False):
返回一个叫做 typename 的tuple子类,这个新的子类用来创建类tuple(tuple-like)的对象,这个对象拥有可以通过属性访问的字段,并且可以通过下标索引和迭代。
field_names 是一个单独的字符串,这个字符串中包含的所有字段用空格或逗号隔开,例如 'xy'
或 'x,y'
.另外, field_names 也可以是字符串的列表,例如 ['x', 'y']。
如果verbose 为 True, 在类被建立后将打印类的定义。相反,它打印的是类的 _source
属性,也就是打印源代码。
如果 rename参数 为 True, 无效的field_names会被自动转换成位置的名称.例如, ['abc', 'def', 'ghi', 'abc']
将被转换为 ['abc', '_1', 'ghi', '_3']
, 来消除关键字 def
和重复的字段名 abc。
2)可命名元组的创建
需要先创建一个类。
from collections import namedtuple myTupleClass=namedtuple('myTupleClass',['x','y']) a=point(1,2) b=point(2,0) print(a,a.x,a.y,type(a)) print(b,b.x,b.y,type(b)) #运行结果 myTupleClass(x=1, y=2) 1 2 <class '__main__.myTupleClass'> myTupleClass(x=2, y=0) 2 0 <class '__main__.myTupleClass'>
3)可命名元组新创建类的功能属性
如上面创建的myTupleCalss类:
1 print(help(myTupleClass)) #运行help打印获取 2 3 class myTupleClass(builtins.tuple) 4 | myTupleClass(x, y) 5 | 6 | Method resolution order: 7 | myTupleClass 8 | builtins.tuple 9 | builtins.object 10 | 11 | Methods defined here: 12 | 13 | __getnewargs__(self) 14 | Return self as a plain tuple. Used by copy and pickle. 15 | 16 | __repr__(self) 17 | Return a nicely formatted representation string 18 | 19 | _asdict(self) 20 | Return a new OrderedDict which maps field names to their values. 21 | 22 | _replace(_self, **kwds) 23 | Return a new myTupleClass object replacing specified fields with new values 24 | 25 | ---------------------------------------------------------------------- 26 | Class methods defined here: 27 | 28 | _make(iterable, new=<built-in method __new__ of type object at 0x6143B5C8>, len=<built-in function len>) from builtins.type 29 | Make a new myTupleClass object from a sequence or iterable 30 | 31 | ---------------------------------------------------------------------- 32 | Static methods defined here: 33 | 34 | __new__(_cls, x, y) 35 | Create new instance of myTupleClass(x, y) 36 | 37 | ---------------------------------------------------------------------- 38 | Data descriptors defined here: 39 | 40 | x 41 | Alias for field number 0 42 | 43 | y 44 | Alias for field number 1 45 | 46 | ---------------------------------------------------------------------- 47 | Data and other attributes defined here: 48 | 49 | _fields = ('x', 'y') 50 | 51 | _source = "from builtins import property as _property, tupl..._itemget... 52 | 53 | ---------------------------------------------------------------------- 54 | Methods inherited from builtins.tuple: 55 | 56 | __add__(self, value, /) 57 | Return self+value. 58 | 59 | __contains__(self, key, /) 60 | Return key in self. 61 | 62 | __eq__(self, value, /) 63 | Return self==value. 64 | 65 | __ge__(self, value, /) 66 | Return self>=value. 67 | 68 | __getattribute__(self, name, /) 69 | Return getattr(self, name). 70 | 71 | __getitem__(self, key, /) 72 | Return self[key]. 73 | 74 | __gt__(self, value, /) 75 | Return self>value. 76 | 77 | __hash__(self, /) 78 | Return hash(self). 79 | 80 | __iter__(self, /) 81 | Implement iter(self). 82 | 83 | __le__(self, value, /) 84 | Return self<=value. 85 | 86 | __len__(self, /) 87 | Return len(self). 88 | 89 | __lt__(self, value, /) 90 | Return self<value. 91 | 92 | __mul__(self, value, /) 93 | Return self*value.n 94 | 95 | __ne__(self, value, /) 96 | Return self!=value. 97 | 98 | __rmul__(self, value, /) 99 | Return self*value. 100 | 101 | count(...) 102 | T.count(value) -> integer -- return number of occurrences of value 103 | 104 | index(...) 105 | T.index(value, [start, [stop]]) -> integer -- return first index of value. 106 | Raises ValueError if the value is not present. 107 108 None
5.队列(deque)
1)双向队列(deque)
双向队列(Deque)是栈和队列的一般化。可以在两端添加和删除元素。
双向队列的创建:
from collections import deque a=deque() b=deque('abcd') print(a,type(a)) print(b,type(b)) #运行结果 deque([]) <class 'collections.deque'> deque(['a', 'b', 'c', 'd']) <class 'collections.deque'>
双向队列的功能属性:
1 class deque(object): 2 """ 3 deque([iterable[, maxlen]]) --> deque object 4 5 A list-like sequence optimized for data accesses near its endpoints. 6 """ 7 def append(self, *args, **kwargs): # real signature unknown 8 """ Add an element to the right side of the deque. """ 9 pass 10 11 def appendleft(self, *args, **kwargs): # real signature unknown 12 """ Add an element to the left side of the deque. """ 13 pass 14 15 def clear(self, *args, **kwargs): # real signature unknown 16 """ Remove all elements from the deque. """ 17 pass 18 19 def copy(self, *args, **kwargs): # real signature unknown 20 """ Return a shallow copy of a deque. """ 21 pass 22 23 def count(self, value): # real signature unknown; restored from __doc__ 24 """ D.count(value) -> integer -- return number of occurrences of value """ 25 return 0 26 27 def extend(self, *args, **kwargs): # real signature unknown 28 """ Extend the right side of the deque with elements from the iterable """ 29 pass 30 31 def extendleft(self, *args, **kwargs): # real signature unknown 32 """ Extend the left side of the deque with elements from the iterable """ 33 pass 34 35 def index(self, value, start=None, stop=None): # real signature unknown; restored from __doc__ 36 """ 37 D.index(value, [start, [stop]]) -> integer -- return first index of value. 38 Raises ValueError if the value is not present. 39 """ 40 return 0 41 42 def insert(self, index, p_object): # real signature unknown; restored from __doc__ 43 """ D.insert(index, object) -- insert object before index """ 44 pass 45 46 def pop(self, *args, **kwargs): # real signature unknown 47 """ Remove and return the rightmost element. """ 48 pass 49 50 def popleft(self, *args, **kwargs): # real signature unknown 51 """ Remove and return the leftmost element. """ 52 pass 53 54 def remove(self, value): # real signature unknown; restored from __doc__ 55 """ D.remove(value) -- remove first occurrence of value. """ 56 pass 57 58 def reverse(self): # real signature unknown; restored from __doc__ 59 """ D.reverse() -- reverse *IN PLACE* """ 60 pass 61 62 def rotate(self, *args, **kwargs): # real signature unknown 63 """ Rotate the deque n steps to the right (default n=1). If n is negative, rotates left. """ 64 pass 65 66 def __add__(self, *args, **kwargs): # real signature unknown 67 """ Return self+value. """ 68 pass 69 70 def __bool__(self, *args, **kwargs): # real signature unknown 71 """ self != 0 """ 72 pass 73 74 def __contains__(self, *args, **kwargs): # real signature unknown 75 """ Return key in self. """ 76 pass 77 78 def __copy__(self, *args, **kwargs): # real signature unknown 79 """ Return a shallow copy of a deque. """ 80 pass 81 82 def __delitem__(self, *args, **kwargs): # real signature unknown 83 """ Delete self[key]. """ 84 pass 85 86 def __eq__(self, *args, **kwargs): # real signature unknown 87 """ Return self==value. """ 88 pass 89 90 def __getattribute__(self, *args, **kwargs): # real signature unknown 91 """ Return getattr(self, name). """ 92 pass 93 94 def __getitem__(self, *args, **kwargs): # real signature unknown 95 """ Return self[key]. """ 96 pass 97 98 def __ge__(self, *args, **kwargs): # real signature unknown 99 """ Return self>=value. """ 100 pass 101 102 def __gt__(self, *args, **kwargs): # real signature unknown 103 """ Return self>value. """ 104 pass 105 106 def __iadd__(self, *args, **kwargs): # real signature unknown 107 """ Implement self+=value. """ 108 pass 109 110 def __imul__(self, *args, **kwargs): # real signature unknown 111 """ Implement self*=value. """ 112 pass 113 114 def __init__(self, iterable=(), maxlen=None): # known case of _collections.deque.__init__ 115 """ 116 deque([iterable[, maxlen]]) --> deque object 117 118 A list-like sequence optimized for data accesses near its endpoints. 119 # (copied from class doc) 120 """ 121 pass 122 123 def __iter__(self, *args, **kwargs): # real signature unknown 124 """ Implement iter(self). """ 125 pass 126 127 def __len__(self, *args, **kwargs): # real signature unknown 128 """ Return len(self). """ 129 pass 130 131 def __le__(self, *args, **kwargs): # real signature unknown 132 """ Return self<=value. """ 133 pass 134 135 def __lt__(self, *args, **kwargs): # real signature unknown 136 """ Return self<value. """ 137 pass 138 139 def __mul__(self, *args, **kwargs): # real signature unknown 140 """ Return self*value.n """ 141 pass 142 143 @staticmethod # known case of __new__ 144 def __new__(*args, **kwargs): # real signature unknown 145 """ Create and return a new object. See help(type) for accurate signature. """ 146 pass 147 148 def __ne__(self, *args, **kwargs): # real signature unknown 149 """ Return self!=value. """ 150 pass 151 152 def __reduce__(self, *args, **kwargs): # real signature unknown 153 """ Return state information for pickling. """ 154 pass 155 156 def __repr__(self, *args, **kwargs): # real signature unknown 157 """ Return repr(self). """ 158 pass 159 160 def __reversed__(self): # real signature unknown; restored from __doc__ 161 """ D.__reversed__() -- return a reverse iterator over the deque """ 162 pass 163 164 def __rmul__(self, *args, **kwargs): # real signature unknown 165 """ Return self*value. """ 166 pass 167 168 def __setitem__(self, *args, **kwargs): # real signature unknown 169 """ Set self[key] to value. """ 170 pass 171 172 def __sizeof__(self): # real signature unknown; restored from __doc__ 173 """ D.__sizeof__() -- size of D in memory, in bytes """ 174 pass 175 176 maxlen = property(lambda self: object(), lambda self, v: None, lambda self: None) # default 177 """maximum size of a deque or None if unbounded""" 178 179 180 __hash__ = None
2)单向队列(queue.Queue)
class queue.
Queue
(maxsize=0)
单向队列与双向队列的区别是FIFO(先进先出),maxsize是个整数,指明了队列中能存放的数据个数的上限。一旦达到上限,插入会导致阻塞,直到队列中的数据被取出。如果maxsize小于或者等于0,则队列大小没有限制。
单向队列的创建:
import queue a=queue.Queue() b=queue.Queue('abcd') print(a,type(a)) print(b,type(b)) #运行结果 <queue.Queue object at 0x00FBB310> <class 'queue.Queue'> <queue.Queue object at 0x01522DF0> <class 'queue.Queue'>
单向队列的功能属性:
1 class Queue: 2 '''Create a queue object with a given maximum size. 3 4 If maxsize is <= 0, the queue size is infinite. 5 ''' 6 7 def __init__(self, maxsize=0): 8 self.maxsize = maxsize 9 self._init(maxsize) 10 11 # mutex must be held whenever the queue is mutating. All methods 12 # that acquire mutex must release it before returning. mutex 13 # is shared between the three conditions, so acquiring and 14 # releasing the conditions also acquires and releases mutex. 15 self.mutex = threading.Lock() 16 17 # Notify not_empty whenever an item is added to the queue; a 18 # thread waiting to get is notified then. 19 self.not_empty = threading.Condition(self.mutex) 20 21 # Notify not_full whenever an item is removed from the queue; 22 # a thread waiting to put is notified then. 23 self.not_full = threading.Condition(self.mutex) 24 25 # Notify all_tasks_done whenever the number of unfinished tasks 26 # drops to zero; thread waiting to join() is notified to resume 27 self.all_tasks_done = threading.Condition(self.mutex) 28 self.unfinished_tasks = 0 29 30 def task_done(self): 31 '''Indicate that a formerly enqueued task is complete. 32 33 Used by Queue consumer threads. For each get() used to fetch a task, 34 a subsequent call to task_done() tells the queue that the processing 35 on the task is complete. 36 37 If a join() is currently blocking, it will resume when all items 38 have been processed (meaning that a task_done() call was received 39 for every item that had been put() into the queue). 40 41 Raises a ValueError if called more times than there were items 42 placed in the queue. 43 ''' 44 with self.all_tasks_done: 45 unfinished = self.unfinished_tasks - 1 46 if unfinished <= 0: 47 if unfinished < 0: 48 raise ValueError('task_done() called too many times') 49 self.all_tasks_done.notify_all() 50 self.unfinished_tasks = unfinished 51 52 def join(self): 53 '''Blocks until all items in the Queue have been gotten and processed. 54 55 The count of unfinished tasks goes up whenever an item is added to the 56 queue. The count goes down whenever a consumer thread calls task_done() 57 to indicate the item was retrieved and all work on it is complete. 58 59 When the count of unfinished tasks drops to zero, join() unblocks. 60 ''' 61 with self.all_tasks_done: 62 while self.unfinished_tasks: 63 self.all_tasks_done.wait() 64 65 def qsize(self): 66 '''Return the approximate size of the queue (not reliable!).''' 67 with self.mutex: 68 return self._qsize() 69 70 def empty(self): 71 '''Return True if the queue is empty, False otherwise (not reliable!). 72 73 This method is likely to be removed at some point. Use qsize() == 0 74 as a direct substitute, but be aware that either approach risks a race 75 condition where a queue can grow before the result of empty() or 76 qsize() can be used. 77 78 To create code that needs to wait for all queued tasks to be 79 completed, the preferred technique is to use the join() method. 80 ''' 81 with self.mutex: 82 return not self._qsize() 83 84 def full(self): 85 '''Return True if the queue is full, False otherwise (not reliable!). 86 87 This method is likely to be removed at some point. Use qsize() >= n 88 as a direct substitute, but be aware that either approach risks a race 89 condition where a queue can shrink before the result of full() or 90 qsize() can be used. 91 ''' 92 with self.mutex: 93 return 0 < self.maxsize <= self._qsize() 94 95 def put(self, item, block=True, timeout=None): 96 '''Put an item into the queue. 97 98 If optional args 'block' is true and 'timeout' is None (the default), 99 block if necessary until a free slot is available. If 'timeout' is 100 a non-negative number, it blocks at most 'timeout' seconds and raises 101 the Full exception if no free slot was available within that time. 102 Otherwise ('block' is false), put an item on the queue if a free slot 103 is immediately available, else raise the Full exception ('timeout' 104 is ignored in that case). 105 ''' 106 with self.not_full: 107 if self.maxsize > 0: 108 if not block: 109 if self._qsize() >= self.maxsize: 110 raise Full 111 elif timeout is None: 112 while self._qsize() >= self.maxsize: 113 self.not_full.wait() 114 elif timeout < 0: 115 raise ValueError("'timeout' must be a non-negative number") 116 else: 117 endtime = time() + timeout 118 while self._qsize() >= self.maxsize: 119 remaining = endtime - time() 120 if remaining <= 0.0: 121 raise Full 122 self.not_full.wait(remaining) 123 self._put(item) 124 self.unfinished_tasks += 1 125 self.not_empty.notify() 126 127 def get(self, block=True, timeout=None): 128 '''Remove and return an item from the queue. 129 130 If optional args 'block' is true and 'timeout' is None (the default), 131 block if necessary until an item is available. If 'timeout' is 132 a non-negative number, it blocks at most 'timeout' seconds and raises 133 the Empty exception if no item was available within that time. 134 Otherwise ('block' is false), return an item if one is immediately 135 available, else raise the Empty exception ('timeout' is ignored 136 in that case). 137 ''' 138 with self.not_empty: 139 if not block: 140 if not self._qsize(): 141 raise Empty 142 elif timeout is None: 143 while not self._qsize(): 144 self.not_empty.wait() 145 elif timeout < 0: 146 raise ValueError("'timeout' must be a non-negative number") 147 else: 148 endtime = time() + timeout 149 while not self._qsize(): 150 remaining = endtime - time() 151 if remaining <= 0.0: 152 raise Empty 153 self.not_empty.wait(remaining) 154 item = self._get() 155 self.not_full.notify() 156 return item 157 158 def put_nowait(self, item): 159 '''Put an item into the queue without blocking. 160 161 Only enqueue the item if a free slot is immediately available. 162 Otherwise raise the Full exception. 163 ''' 164 return self.put(item, block=False) 165 166 def get_nowait(self): 167 '''Remove and return an item from the queue without blocking. 168 169 Only get an item if one is immediately available. Otherwise 170 raise the Empty exception. 171 ''' 172 return self.get(block=False) 173 174 # Override these methods to implement other queue organizations 175 # (e.g. stack or priority queue). 176 # These will only be called with appropriate locks held 177 178 # Initialize the queue representation 179 def _init(self, maxsize): 180 self.queue = deque() 181 182 def _qsize(self): 183 return len(self.queue) 184 185 # Put a new item in the queue 186 def _put(self, item): 187 self.queue.append(item) 188 189 # Get an item from the queue 190 def _get(self): 191 return self.queue.popleft()
6.深浅拷贝
官方文档网址:https://docs.python.org/3/library/copy.html
浅拷贝和深拷贝的主要区别在与操作后内存地址的变化是不同的。
具体区别参见博文:http://www.cnblogs.com/wupeiqi/articles/5453708.html