Commit 5f516edd authored by Raymond Hettinger's avatar Raymond Hettinger

Add count() method to collections.deque().

parent 30583e3f
...@@ -358,6 +358,12 @@ counts, but the output will exclude results with counts of zero or less. ...@@ -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. 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) .. method:: extend(iterable)
Extend the right side of the deque by appending elements from the iterable Extend the right side of the deque by appending elements from the iterable
......
...@@ -113,6 +113,13 @@ class TestBasic(unittest.TestCase): ...@@ -113,6 +113,13 @@ class TestBasic(unittest.TestCase):
d = deque('abc') d = deque('abc')
d.maxlen = 10 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): def test_comparisons(self):
d = deque('xabc'); d.popleft() d = deque('xabc'); d.popleft()
for e in [d, deque('abc'), deque('ab'), deque(), list(d)]: for e in [d, deque('abc'), deque('ab'), deque(), list(d)]:
......
...@@ -1223,7 +1223,7 @@ Core and Builtins ...@@ -1223,7 +1223,7 @@ Core and Builtins
Library 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 - Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d
......
...@@ -504,6 +504,46 @@ deque_reverse(dequeobject *deque, PyObject *unused) ...@@ -504,6 +504,46 @@ deque_reverse(dequeobject *deque, PyObject *unused)
PyDoc_STRVAR(reverse_doc, PyDoc_STRVAR(reverse_doc,
"D.reverse() -- reverse *IN PLACE*"); "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 static Py_ssize_t
deque_len(dequeobject *deque) deque_len(dequeobject *deque)
{ {
...@@ -991,6 +1031,8 @@ static PyMethodDef deque_methods[] = { ...@@ -991,6 +1031,8 @@ static PyMethodDef deque_methods[] = {
METH_NOARGS, clear_doc}, METH_NOARGS, clear_doc},
{"__copy__", (PyCFunction)deque_copy, {"__copy__", (PyCFunction)deque_copy,
METH_NOARGS, copy_doc}, METH_NOARGS, copy_doc},
{"count", (PyCFunction)deque_count,
METH_O, count_doc},
{"extend", (PyCFunction)deque_extend, {"extend", (PyCFunction)deque_extend,
METH_O, extend_doc}, METH_O, extend_doc},
{"extendleft", (PyCFunction)deque_extendleft, {"extendleft", (PyCFunction)deque_extendleft,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment