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

index dc81c0ad1834a749ba0bf9647d4687c26ab84ffa..db9babfdaa36596503f1ad063488cea9b1ff7402 100644 (file)
@@ -379,6 +379,11 @@ counts, but the output will exclude results with counts of zero or less.
 
       .. versionadded:: 2.5
 
+   .. method:: reverse()
+
+      Reverse the elements of the deque in-place and then return ``None``.
+
+      .. versionadded:: 2.7
 
    .. method:: rotate(n)
 
index 23641ba18dcc21432c734f726c7cf80544599672..c1f1667a008a34b69cd2da1833bc6f82c4b7f077 100644 (file)
@@ -204,6 +204,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 3cd0b4259e9c1af8ed7b5714906c16df3a64c39c..e4c39185082cb3bd3b59b7991d68e8b8501da35a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -513,6 +513,8 @@ Core and Builtins
 Library
 -------
 
+- Add a reverse() method to collections.deque().
+
 - Fix variations of extending deques:  d.extend(d)  d.extendleft(d)  d+=d
 
 - Issue #6986: Fix crash in the JSON C accelerator when called with the
index 97b390539ffdb8e00e48f083af6d438275574470..978bd9a4bb00e53f4dff9428a8ecaa9563164825 100644 (file)
@@ -462,6 +462,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)
 {
@@ -963,6 +1005,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 */