From: Raymond Hettinger Date: Thu, 10 Dec 2009 00:47:21 +0000 (+0000) Subject: Add a reverse() method to collections.deque(). X-Git-Tag: v3.2a1~2064 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e5fdedbeda147f3878f82349464f28f184c01658;p=python Add a reverse() method to collections.deque(). --- diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 7770b8951b..2ee294935c 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -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) diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index 1a03188e12..cdb0dab0f0 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -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) diff --git a/Misc/NEWS b/Misc/NEWS index 3915e9b1a3..ddf9a04407 100644 --- 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. diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 68e01836cb..cdcf4ef988 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -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 ; idata[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 */