collections
collections
collections是Python内建的一个集合模块,提供了许多有用的集合类。
调用collections的方法:
在程序前面添加
import collections
或
from collections import * #$ 以下示例都使用这种方式
计数器(counter)
counter的作用是统计元素出现的次数。
1 #!/usr/bin/env python3 2 import collections 3 n = ('d','d','d','c','t','s') 4 c = collections.Counter(n)
结果:
Counter({'d': 3, 's': 1, 'c': 1, 't': 1})
counter的方法
1 class Counter(dict): 2 #$ 继承了dict的方法 3 '''Dict subclass for counting hashable items. Sometimes called a bag 4 or multiset. Elements are stored as dictionary keys and their counts 5 are stored as dictionary values. 6 7 >>> c = Counter('abcdeabcdabcaba') # count elements from a string 8 9 >>> c.most_common(3) # three most common elements 10 [('a', 5), ('b', 4), ('c', 3)] 11 >>> sorted(c) # list all unique elements 12 ['a', 'b', 'c', 'd', 'e'] 13 >>> ''.join(sorted(c.elements())) # list elements with repetitions 14 'aaaaabbbbcccdde' 15 >>> sum(c.values()) # total of all counts 16 15 17 18 >>> c['a'] # count of letter 'a' 19 5 20 >>> for elem in 'shazam': # update counts from an iterable 21 ... c[elem] += 1 # by adding 1 to each element's count 22 >>> c['a'] # now there are seven 'a' 23 7 24 >>> del c['b'] # remove all 'b' 25 >>> c['b'] # now there are zero 'b' 26 0 27 28 >>> d = Counter('simsalabim') # make another counter 29 >>> c.update(d) # add in the second counter 30 >>> c['a'] # now there are nine 'a' 31 9 32 33 >>> c.clear() # empty the counter 34 >>> c 35 Counter() 36 37 Note: If a count is set to zero or reduced to zero, it will remain 38 in the counter until the entry is deleted or the counter is cleared: 39 40 >>> c = Counter('aaabbc') 41 >>> c['b'] -= 2 # reduce the count of 'b' by two 42 >>> c.most_common() # 'b' is still in, but its count is zero 43 [('a', 3), ('c', 1), ('b', 0)] 44 45 ''' 46 # References: 47 # http://en.wikipedia.org/wiki/Multiset 48 # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html 49 # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm 50 # http://code.activestate.com/recipes/259174/ 51 # Knuth, TAOCP Vol. II section 4.6.3 52 53 def __init__(*args, **kwds): 54 '''Create a new, empty Counter object. And if given, count elements 55 from an input iterable. Or, initialize the count from another mapping 56 of elements to their counts. 57 58 >>> c = Counter() # a new, empty counter 59 >>> c = Counter('gallahad') # a new counter from an iterable 60 >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping 61 >>> c = Counter(a=4, b=2) # a new counter from keyword args 62 63 ''' 64 if not args: 65 raise TypeError("descriptor '__init__' of 'Counter' object " 66 "needs an argument") 67 self, *args = args 68 if len(args) > 1: 69 raise TypeError('expected at most 1 arguments, got %d' % len(args)) 70 super(Counter, self).__init__() 71 self.update(*args, **kwds) 72 73 def __missing__(self, key): 74 'The count of elements not in the Counter is zero.' 75 # Needed so that self[missing_item] does not raise KeyError 76 return 0 77 78 def most_common(self, n=None): 79 '''List the n most common elements and their counts from the most 80 common to the least. If n is None, then list all element counts. 81 82 >>> Counter('abcdeabcdabcaba').most_common(3) 83 [('a', 5), ('b', 4), ('c', 3)] 84 85 ''' 86 # Emulate Bag.sortedByCount from Smalltalk 87 if n is None: 88 return sorted(self.items(), key=_itemgetter(1), reverse=True) 89 return _heapq.nlargest(n, self.items(), key=_itemgetter(1)) 90 91 def elements(self): 92 '''Iterator over elements repeating each as many times as its count. 93 94 >>> c = Counter('ABCABC') 95 >>> sorted(c.elements()) 96 ['A', 'A', 'B', 'B', 'C', 'C'] 97 98 # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1 99 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) 100 >>> product = 1 101 >>> for factor in prime_factors.elements(): # loop over factors 102 ... product *= factor # and multiply them 103 >>> product 104 1836 105 106 Note, if an element's count has been set to zero or is a negative 107 number, elements() will ignore it. 108 109 ''' 110 # Emulate Bag.do from Smalltalk and Multiset.begin from C++. 111 return _chain.from_iterable(_starmap(_repeat, self.items())) 112 113 # Override dict methods where necessary 114 115 @classmethod 116 def fromkeys(cls, iterable, v=None): 117 # There is no equivalent method for counters because setting v=1 118 # means that no element can have a count greater than one. 119 raise NotImplementedError( 120 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') 121 122 def update(*args, **kwds): 123 '''Like dict.update() but add counts instead of replacing them. 124 125 Source can be an iterable, a dictionary, or another Counter instance. 126 127 >>> c = Counter('which') 128 >>> c.update('witch') # add elements from another iterable 129 >>> d = Counter('watch') 130 >>> c.update(d) # add elements from another counter 131 >>> c['h'] # four 'h' in which, witch, and watch 132 4 133 134 ''' 135 # The regular dict.update() operation makes no sense here because the 136 # replace behavior results in the some of original untouched counts 137 # being mixed-in with all of the other counts for a mismash that 138 # doesn't have a straight-forward interpretation in most counting 139 # contexts. Instead, we implement straight-addition. Both the inputs 140 # and outputs are allowed to contain zero and negative counts. 141 142 if not args: 143 raise TypeError("descriptor 'update' of 'Counter' object " 144 "needs an argument") 145 self, *args = args 146 if len(args) > 1: 147 raise TypeError('expected at most 1 arguments, got %d' % len(args)) 148 iterable = args[0] if args else None 149 if iterable is not None: 150 if isinstance(iterable, Mapping): 151 if self: 152 self_get = self.get 153 for elem, count in iterable.items(): 154 self[elem] = count + self_get(elem, 0) 155 else: 156 super(Counter, self).update(iterable) # fast path when counter is empty 157 else: 158 _count_elements(self, iterable) 159 if kwds: 160 self.update(kwds) 161 162 def subtract(*args, **kwds): 163 '''Like dict.update() but subtracts counts instead of replacing them. 164 Counts can be reduced below zero. Both the inputs and outputs are 165 allowed to contain zero and negative counts. 166 167 Source can be an iterable, a dictionary, or another Counter instance. 168 169 >>> c = Counter('which') 170 >>> c.subtract('witch') # subtract elements from another iterable 171 >>> c.subtract(Counter('watch')) # subtract elements from another counter 172 >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch 173 0 174 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch 175 -1 176 177 ''' 178 if not args: 179 raise TypeError("descriptor 'subtract' of 'Counter' object " 180 "needs an argument") 181 self, *args = args 182 if len(args) > 1: 183 raise TypeError('expected at most 1 arguments, got %d' % len(args)) 184 iterable = args[0] if args else None 185 if iterable is not None: 186 self_get = self.get 187 if isinstance(iterable, Mapping): 188 for elem, count in iterable.items(): 189 self[elem] = self_get(elem, 0) - count 190 else: 191 for elem in iterable: 192 self[elem] = self_get(elem, 0) - 1 193 if kwds: 194 self.subtract(kwds) 195 196 def copy(self): 197 'Return a shallow copy.' 198 return self.__class__(self) 199 200 def __reduce__(self): 201 return self.__class__, (dict(self),) 202 203 def __delitem__(self, elem): 204 'Like dict.__delitem__() but does not raise KeyError for missing values.' 205 if elem in self: 206 super().__delitem__(elem) 207 208 def __repr__(self): 209 if not self: 210 return '%s()' % self.__class__.__name__ 211 try: 212 items = ', '.join(map('%r: %r'.__mod__, self.most_common())) 213 return '%s({%s})' % (self.__class__.__name__, items) 214 except TypeError: 215 # handle case where values are not orderable 216 return '{0}({1!r})'.format(self.__class__.__name__, dict(self)) 217 218 # Multiset-style mathematical operations discussed in: 219 # Knuth TAOCP Volume II section 4.6.3 exercise 19 220 # and at http://en.wikipedia.org/wiki/Multiset 221 # 222 # Outputs guaranteed to only include positive counts. 223 # 224 # To strip negative and zero counts, add-in an empty counter: 225 # c += Counter() 226 227 def __add__(self, other): 228 '''Add counts from two counters. 229 230 >>> Counter('abbb') + Counter('bcc') 231 Counter({'b': 4, 'c': 2, 'a': 1}) 232 233 ''' 234 if not isinstance(other, Counter): 235 return NotImplemented 236 result = Counter() 237 for elem, count in self.items(): 238 newcount = count + other[elem] 239 if newcount > 0: 240 result[elem] = newcount 241 for elem, count in other.items(): 242 if elem not in self and count > 0: 243 result[elem] = count 244 return result 245 246 def __sub__(self, other): 247 ''' Subtract count, but keep only results with positive counts. 248 249 >>> Counter('abbbc') - Counter('bccd') 250 Counter({'b': 2, 'a': 1}) 251 252 ''' 253 if not isinstance(other, Counter): 254 return NotImplemented 255 result = Counter() 256 for elem, count in self.items(): 257 newcount = count - other[elem] 258 if newcount > 0: 259 result[elem] = newcount 260 for elem, count in other.items(): 261 if elem not in self and count < 0: 262 result[elem] = 0 - count 263 return result 264 265 def __or__(self, other): 266 '''Union is the maximum of value in either of the input counters. 267 268 >>> Counter('abbb') | Counter('bcc') 269 Counter({'b': 3, 'c': 2, 'a': 1}) 270 271 ''' 272 if not isinstance(other, Counter): 273 return NotImplemented 274 result = Counter() 275 for elem, count in self.items(): 276 other_count = other[elem] 277 newcount = other_count if count < other_count else count 278 if newcount > 0: 279 result[elem] = newcount 280 for elem, count in other.items(): 281 if elem not in self and count > 0: 282 result[elem] = count 283 return result 284 285 def __and__(self, other): 286 ''' Intersection is the minimum of corresponding counts. 287 288 >>> Counter('abbb') & Counter('bcc') 289 Counter({'b': 1}) 290 291 ''' 292 if not isinstance(other, Counter): 293 return NotImplemented 294 result = Counter() 295 for elem, count in self.items(): 296 other_count = other[elem] 297 newcount = count if count < other_count else other_count 298 if newcount > 0: 299 result[elem] = newcount 300 return result 301 302 def __pos__(self): 303 'Adds an empty counter, effectively stripping negative and zero counts' 304 result = Counter() 305 for elem, count in self.items(): 306 if count > 0: 307 result[elem] = count 308 return result 309 310 def __neg__(self): 311 '''Subtracts from an empty counter. Strips positive and zero counts, 312 and flips the sign on negative counts. 313 314 ''' 315 result = Counter() 316 for elem, count in self.items(): 317 if count < 0: 318 result[elem] = 0 - count 319 return result 320 321 def _keep_positive(self): 322 '''Internal method to strip elements with a negative or zero count''' 323 nonpositive = [elem for elem, count in self.items() if not count > 0] 324 for elem in nonpositive: 325 del self[elem] 326 return self 327 328 def __iadd__(self, other): 329 '''Inplace add from another counter, keeping only positive counts. 330 331 >>> c = Counter('abbb') 332 >>> c += Counter('bcc') 333 >>> c 334 Counter({'b': 4, 'c': 2, 'a': 1}) 335 336 ''' 337 for elem, count in other.items(): 338 self[elem] += count 339 return self._keep_positive() 340 341 def __isub__(self, other): 342 '''Inplace subtract counter, but keep only results with positive counts. 343 344 >>> c = Counter('abbbc') 345 >>> c -= Counter('bccd') 346 >>> c 347 Counter({'b': 2, 'a': 1}) 348 349 ''' 350 for elem, count in other.items(): 351 self[elem] -= count 352 return self._keep_positive() 353 354 def __ior__(self, other): 355 '''Inplace union is the maximum of value from either counter. 356 357 >>> c = Counter('abbb') 358 >>> c |= Counter('bcc') 359 >>> c 360 Counter({'b': 3, 'c': 2, 'a': 1}) 361 362 ''' 363 for elem, other_count in other.items(): 364 count = self[elem] 365 if other_count > count: 366 self[elem] = other_count 367 return self._keep_positive() 368 369 def __iand__(self, other): 370 '''Inplace intersection is the minimum of corresponding counts. 371 372 >>> c = Counter('abbb') 373 >>> c &= Counter('bcc') 374 >>> c 375 Counter({'b': 1}) 376 377 ''' 378 for elem, count in self.items(): 379 other_count = other[elem] 380 if other_count < count: 381 self[elem] = other_count 382 return self._keep_positive()
most_common()
作用:显示数量大于n的元素和计数器
>>> Counter('dfshhfdhdfhdfadf').most_common(3)
[('f', 5), ('d', 5), ('h', 4)]
update()
作用:增加计数器,如果原来有则增加,如果原来没有则新建
>>> c = Counter('hello')
>>> c
Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})
>>> c.update('hello word')
>>> c
Counter({'l': 4, 'o': 3, 'h': 2, 'e': 2, 'd': 1, 'w': 1, 'r': 1, ' ': 1})
subtract()
作用:计数器向减
>>> c = Counter('hello')
>>> c.subtract('hello word')
>>> c
Counter({'h': 0, 'e': 0, 'l': 0, 'd': -1, 'o': -1, 'w': -1, 'r': -1, ' ': -1})
copy()
作用:浅拷贝
>>> c = Counter('hello')
>>> c
Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})
>>> c1 = c.copy()
>>> c1
Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})
__reduce__()
作用:返回一个元组
>>> c = Counter('hello')
>>> c.__reduce__()
(<class 'collections.Counter'>, ({'l': 2, 'h': 1, 'e': 1, 'o': 1},))
__delitem__()
作用:删除元素
>>> c = Counter('hello')
>>> c.__delitem__('l')
>>> c
Counter({'h': 1, 'e': 1, 'o': 1})
有序字典(orderdDict)
orderdDict是对字典类型的补充,他记住了字典元素添加的顺序
1 class OrderedDict(dict): 2 """ Dictionary that remembers insertion order """ 3 def clear(self): # real signature unknown; restored from __doc__ 4 """ od.clear() -> None. Remove all items from od. """ 5 pass 6 7 def copy(self): # real signature unknown; restored from __doc__ 8 """ od.copy() -> a shallow copy of od """ 9 pass 10 11 @classmethod 12 def fromkeys(cls, S, v=None): # real signature unknown; restored from __doc__ 13 """ 14 OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S. 15 If not specified, the value defaults to None. 16 """ 17 pass 18 19 def items(self, *args, **kwargs): # real signature unknown 20 pass 21 22 def keys(self, *args, **kwargs): # real signature unknown 23 pass 24 25 def move_to_end(self, *args, **kwargs): # real signature unknown 26 """ 27 Move an existing element to the end (or beginning if last==False). 28 29 Raises KeyError if the element does not exist. 30 When last=True, acts like a fast version of self[key]=self.pop(key). 31 """ 32 pass 33 34 def pop(self, k, d=None): # real signature unknown; restored from __doc__ 35 """ 36 od.pop(k[,d]) -> v, remove specified key and return the corresponding 37 value. If key is not found, d is returned if given, otherwise KeyError 38 is raised. 39 """ 40 pass 41 42 def popitem(self): # real signature unknown; restored from __doc__ 43 """ 44 od.popitem() -> (k, v), return and remove a (key, value) pair. 45 Pairs are returned in LIFO order if last is true or FIFO order if false. 46 """ 47 pass 48 49 def setdefault(self, k, d=None): # real signature unknown; restored from __doc__ 50 """ od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od """ 51 pass 52 53 def update(self, *args, **kwargs): # real signature unknown 54 pass 55 56 def values(self, *args, **kwargs): # real signature unknown 57 pass
move_to_end()
默认字典(defaultdict)
defaultdict是对字典的类型的补充,他默认给字典的值设置了一个类型。
例子:
有如下值集合 [
11
,
22
,
33
,
44
,
55
,
66
,
77
,
88
,
99
,
90.
..],将所有大于
66
的值保存至字典的第一个key中,将小于
66
的值保存至第二个key的值中。
即: {
'k1'
: 大于
66
,
'k2'
: 小于
66
}
1 #!/usr/bin/env python3 2 3 from collections import * 4 5 li = [11,22,33,44,55,66,77,88,99,90] 6 dic = defaultdict(list) 7 for i in li: 8 if i > 66: 9 dic['k1'].append(i) 10 else: 11 dic['k2'].append(i) 12 print(dic)
可命名元组(namedtuple)
根据nametuple可以创建一个包含元组所有功能以及其他功能的类型。
例子:
1 #!/usr/bin/env python3 2 #$ 引用 3 from collections import * 4 #$ 定义一个可命名的元组n 5 n = namedtuple('n',['name','age','email']) 6 #$ 在创建一个新的元组的时候,使用可命名元组 7 l = n('bing',28,'binges@12.com') 8 print(l.name) 9 print(l.age) 10 print(l.email)
结果:
bing
28
binges@12.com
队列
队列分为单向队列和双向队列。
双向队列(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
append()
appendleft()
clear()
copy()
count()
extend()
extendleft()
index()
insert()
pop()
popleft()
remove()
reverse()
rotate()
单向队列(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()