Mercurial > cpython-lru_cache-weakref
changeset 57635:8276d00d3100 legacy-trunk
Add a reverse() method to collections.deque().
| author | Raymond Hettinger <python@rcn.com> |
|---|---|
| date | Thu, 10 Dec 2009 06:42:54 +0000 |
| parents | 57ae5d44e731 |
| children | 8b6689c0e5a6 |
| files | Doc/library/collections.rst Lib/test/test_deque.py Misc/NEWS Modules/_collectionsmodule.c |
| diffstat | 4 files changed, 63 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/Doc/library/collections.rst Thu Dec 10 06:00:33 2009 +0000 +++ b/Doc/library/collections.rst Thu Dec 10 06:42:54 2009 +0000 @@ -379,6 +379,11 @@ .. versionadded:: 2.5 + .. method:: reverse() + + Reverse the elements of the deque in-place and then return ``None``. + + .. versionadded:: 2.7 .. method:: rotate(n)
--- a/Lib/test/test_deque.py Thu Dec 10 06:00:33 2009 +0000 +++ b/Lib/test/test_deque.py Thu Dec 10 06:42:54 2009 +0000 @@ -204,6 +204,18 @@ 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)
--- a/Misc/NEWS Thu Dec 10 06:00:33 2009 +0000 +++ b/Misc/NEWS Thu Dec 10 06:42:54 2009 +0000 @@ -513,6 +513,8 @@ 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
--- a/Modules/_collectionsmodule.c Thu Dec 10 06:00:33 2009 +0000 +++ b/Modules/_collectionsmodule.c Thu Dec 10 06:42:54 2009 +0000 @@ -462,6 +462,48 @@ 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 @@ 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 */
