]> granicus.if.org Git - python/commitdiff
Add a reverse() method to collections.deque().
authorRaymond Hettinger <python@rcn.com>
Thu, 10 Dec 2009 00:47:21 +0000 (00:47 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 10 Dec 2009 00:47:21 +0000 (00:47 +0000)
Doc/library/collections.rst
Lib/test/test_deque.py
Misc/NEWS
Modules/_collectionsmodule.c

index 7770b8951bc637ad78eb9f6e3892dd93dfde043f..2ee294935c7a93a943d9072674394ee4173710db 100644 (file)
@@ -357,6 +357,11 @@ counts, but the output will exclude results with counts of zero or less.
       Removed the first occurrence of *value*.  If not found, raises a
       :exc:`ValueError`.
 
+   .. method:: reverse()
+
+      Reverse the elements of the deque in-place and then return ``None``.
+
+      .. versionadded:: 3.2
 
    .. method:: rotate(n)
 
index 1a03188e12cbb6a29e33a8e56b9b09d3d476da46..cdb0dab0f040f9004d89481ca2d3a15365f7407d 100644 (file)
@@ -193,6 +193,18 @@ class TestBasic(unittest.TestCase):
             self.assertTrue(val not in d)
         self.assertEqual(len(d), 0)
 
+    def test_reverse(self):
+        n = 500         # O(n**2) test, don't make this too big
+        data = [random.random() for i in range(n)]
+        for i in range(n):
+            d = deque(data[:i])
+            r = d.reverse()
+            self.assertEqual(list(d), list(reversed(data[:i])))
+            self.assert_(r is None)
+            d.reverse()
+            self.assertEqual(list(d), data[:i])
+        self.assertRaises(TypeError, d.reverse, 1)          # Arity is zero
+
     def test_rotate(self):
         s = tuple('abcde')
         n = len(s)
index 3915e9b1a32267a8003a5549fa566ea3b8d12e26..ddf9a04407c5b4fccb57fe226bc7604601954eda 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -154,6 +154,8 @@ C-API
 Library
 -------
 
+- Add a reverse() method to collections.deque().
+
 - Issue #6986: Fix crash in the JSON C accelerator when called with the
   wrong parameter types.  Patch by Victor Stinner.
 
index 68e01836cb8764f15ddea5e3d6926a58b1c17272..cdcf4ef9884661acf0c47244f67a2b509a14bb0f 100644 (file)
@@ -427,6 +427,48 @@ deque_rotate(dequeobject *deque, PyObject *args)
 PyDoc_STRVAR(rotate_doc,
 "Rotate the deque n steps to the right (default n=1).  If n is negative, rotates left.");
 
+static PyObject *
+deque_reverse(dequeobject *deque, PyObject *unused)
+{
+       block *leftblock = deque->leftblock;
+       block *rightblock = deque->rightblock;
+       Py_ssize_t leftindex = deque->leftindex;
+       Py_ssize_t rightindex = deque->rightindex;
+       Py_ssize_t n = (deque->len)/2;
+       Py_ssize_t i;
+       PyObject *tmp;
+
+       for (i=0 ; i<n ; i++) {
+               /* Validate that pointers haven't met in the middle */
+               assert(leftblock != rightblock || leftindex < rightindex);
+
+               /* Swap */
+               tmp = leftblock->data[leftindex];
+               leftblock->data[leftindex] = rightblock->data[rightindex];
+               rightblock->data[rightindex] = tmp;
+
+               /* Advance left block/index pair */
+               leftindex++;
+               if (leftindex == BLOCKLEN) {
+                       assert (leftblock->rightlink != NULL);
+                       leftblock = leftblock->rightlink;
+                       leftindex = 0;
+               }
+
+               /* Step backwards with the right block/index pair */
+               rightindex--;
+               if (rightindex == -1) {
+                       assert (rightblock->leftlink != NULL);
+                       rightblock = rightblock->leftlink;
+                       rightindex = BLOCKLEN - 1;
+               }
+       }
+       Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(reverse_doc,
+"D.reverse() -- reverse *IN PLACE*");
+
 static Py_ssize_t
 deque_len(dequeobject *deque)
 {
@@ -865,6 +907,8 @@ static PyMethodDef deque_methods[] = {
                METH_O,          remove_doc},
        {"__reversed__",        (PyCFunction)deque_reviter,
                METH_NOARGS,     reversed_doc},
+       {"reverse",             (PyCFunction)deque_reverse,
+               METH_NOARGS,     reverse_doc},
        {"rotate",              (PyCFunction)deque_rotate,
                METH_VARARGS,   rotate_doc},
        {NULL,          NULL}   /* sentinel */