]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Add count() method to collections.deque().
authorRaymond Hettinger <python@rcn.com>
Sat, 3 Apr 2010 18:10:37 +0000 (18:10 +0000)
committerRaymond Hettinger <python@rcn.com>
Sat, 3 Apr 2010 18:10:37 +0000 (18:10 +0000)
Doc/library/collections.rst
Lib/test/test_deque.py
Misc/NEWS
Modules/_collectionsmodule.c

index 5a6f0de9dfa0e5e144b3a013829ec9946d32196b..f4ba51ab9ad7942f4f623b1fbf9288e0b3de1ef6 100644 (file)
@@ -358,6 +358,12 @@ counts, but the output will exclude results with counts of zero or less.
       Remove all elements from the deque leaving it with length 0.
 
 
+   .. method:: count(x)
+
+      Count the number of deque elements equal to *x*.
+
+      .. versionadded:: 2.7
+
    .. method:: extend(iterable)
 
       Extend the right side of the deque by appending elements from the iterable
index 7de016f66fac3e60c6315221a9c262424f92ba61..3021f6364ef15809abdb4817199468e13765c7c6 100644 (file)
@@ -113,6 +113,13 @@ class TestBasic(unittest.TestCase):
             d = deque('abc')
             d.maxlen = 10
 
+    def test_count(self):
+        for s in ('', 'abracadabra', 'simsalabim'*500+'abc'):
+            s = list(s)
+            d = deque(s)
+            for letter in 'abcdefghijklmnopqrstuvwxyz':
+                self.assertEqual(s.count(letter), d.count(letter), (s, d, letter))
+
     def test_comparisons(self):
         d = deque('xabc'); d.popleft()
         for e in [d, deque('abc'), deque('ab'), deque(), list(d)]:
index e942fb70c3b68bb5adc1c66c0a900681edd3075a..50011456d5ff8a474d9e457f35d79f30198e30bb 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1223,7 +1223,7 @@ Core and Builtins
 Library
 -------
 
-- Add a reverse() method to collections.deque().
+- Add count() and reverse() methods to collections.deque().
 
 - Fix variations of extending deques:  d.extend(d)  d.extendleft(d)  d+=d
 
index 978bd9a4bb00e53f4dff9428a8ecaa9563164825..5d3fc6be27039115a46a4edc4a94fa7f1eb7cd82 100644 (file)
@@ -504,6 +504,46 @@ deque_reverse(dequeobject *deque, PyObject *unused)
 PyDoc_STRVAR(reverse_doc,
 "D.reverse() -- reverse *IN PLACE*");
 
+static PyObject *
+deque_count(dequeobject *deque, PyObject *v)
+{
+       block *leftblock = deque->leftblock;
+       Py_ssize_t leftindex = deque->leftindex;
+       Py_ssize_t n = (deque->len);
+       Py_ssize_t i;
+       Py_ssize_t count = 0;
+       PyObject *item;
+       long start_state = deque->state;
+       int cmp;
+
+       for (i=0 ; i<n ; i++) {
+               item = leftblock->data[leftindex];
+               cmp = PyObject_RichCompareBool(item, v, Py_EQ);
+               if (cmp > 0)
+                       count++;
+               else if (cmp < 0)
+                       return NULL;
+
+               if (start_state != deque->state) {
+                       PyErr_SetString(PyExc_RuntimeError,
+                                       "deque mutated during iteration");
+                       return NULL;
+               }
+
+               /* Advance left block/index pair */
+               leftindex++;
+               if (leftindex == BLOCKLEN) {
+                       assert (leftblock->rightlink != NULL);
+                       leftblock = leftblock->rightlink;
+                       leftindex = 0;
+               }
+       }
+       return PyInt_FromSsize_t(count);
+}
+
+PyDoc_STRVAR(count_doc,
+"D.count(value) -> integer -- return number of occurrences of value");
+
 static Py_ssize_t
 deque_len(dequeobject *deque)
 {
@@ -991,6 +1031,8 @@ static PyMethodDef deque_methods[] = {
                METH_NOARGS,     clear_doc},
        {"__copy__",            (PyCFunction)deque_copy,
                METH_NOARGS,     copy_doc},
+       {"count",               (PyCFunction)deque_count,
+           METH_O,                     count_doc},
        {"extend",              (PyCFunction)deque_extend,
                METH_O,          extend_doc},
        {"extendleft",          (PyCFunction)deque_extendleft,