mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Make deque.rotate() smarter. Beef-up related tests.
This commit is contained in:
parent
3b6d025d9b
commit
ee33b27ef0
2 changed files with 54 additions and 13 deletions
|
@ -41,16 +41,50 @@ class TestBasic(unittest.TestCase):
|
||||||
self.assertEqual(list(d), list(reversed('abcd')))
|
self.assertEqual(list(d), list(reversed('abcd')))
|
||||||
|
|
||||||
def test_rotate(self):
|
def test_rotate(self):
|
||||||
s = 'abcde'
|
s = tuple('abcde')
|
||||||
|
n = len(s)
|
||||||
|
|
||||||
d = deque(s)
|
d = deque(s)
|
||||||
d.rotate(2)
|
d.rotate(1) # verify rot(1)
|
||||||
self.assertEqual(''.join(d), 'deabc')
|
self.assertEqual(''.join(d), 'eabcd')
|
||||||
d.rotate(3)
|
|
||||||
self.assertEqual(''.join(d), s)
|
d = deque(s)
|
||||||
d.rotate(-3)
|
d.rotate(-1) # verify rot(-1)
|
||||||
self.assertEqual(''.join(d), 'deabc')
|
self.assertEqual(''.join(d), 'bcdea')
|
||||||
d.rotate(-15)
|
d.rotate() # check default to 1
|
||||||
self.assertEqual(''.join(d), 'deabc')
|
self.assertEqual(tuple(d), s)
|
||||||
|
|
||||||
|
for i in xrange(n*3):
|
||||||
|
d = deque(s)
|
||||||
|
e = deque(d)
|
||||||
|
d.rotate(i) # check vs. rot(1) n times
|
||||||
|
for j in xrange(i):
|
||||||
|
e.rotate(1)
|
||||||
|
self.assertEqual(tuple(d), tuple(e))
|
||||||
|
d.rotate(-i) # check that it works in reverse
|
||||||
|
self.assertEqual(tuple(d), s)
|
||||||
|
e.rotate(n-i) # check that it wraps forward
|
||||||
|
self.assertEqual(tuple(e), s)
|
||||||
|
|
||||||
|
for i in xrange(n*3):
|
||||||
|
d = deque(s)
|
||||||
|
e = deque(d)
|
||||||
|
d.rotate(-i)
|
||||||
|
for j in xrange(i):
|
||||||
|
e.rotate(-1) # check vs. rot(-1) n times
|
||||||
|
self.assertEqual(tuple(d), tuple(e))
|
||||||
|
d.rotate(i) # check that it works in reverse
|
||||||
|
self.assertEqual(tuple(d), s)
|
||||||
|
e.rotate(i-n) # check that it wraps backaround
|
||||||
|
self.assertEqual(tuple(e), s)
|
||||||
|
|
||||||
|
d = deque(s)
|
||||||
|
e = deque(s)
|
||||||
|
e.rotate(BIG+17) # verify on long series of rotates
|
||||||
|
dr = d.rotate
|
||||||
|
for i in xrange(BIG+17):
|
||||||
|
dr()
|
||||||
|
self.assertEqual(tuple(d), tuple(e))
|
||||||
|
|
||||||
def test_len(self):
|
def test_len(self):
|
||||||
d = deque('ab')
|
d = deque('ab')
|
||||||
|
|
|
@ -247,14 +247,21 @@ PyDoc_STRVAR(extendleft_doc,
|
||||||
static PyObject *
|
static PyObject *
|
||||||
deque_rotate(dequeobject *deque, PyObject *args)
|
deque_rotate(dequeobject *deque, PyObject *args)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n=1, len=deque->len, halflen=(len+1)>>1;
|
||||||
PyObject *item, *rv;
|
PyObject *item, *rv;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "i:rotate", &n))
|
if (!PyArg_ParseTuple(args, "|i:rotate", &n))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (n == 0 || deque->len == 0)
|
if (len == 0)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
if (n > halflen || n < -halflen) {
|
||||||
|
n %= len;
|
||||||
|
if (n > halflen)
|
||||||
|
n -= len;
|
||||||
|
else if (n < -halflen)
|
||||||
|
n += len;
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0 ; i<n ; i++) {
|
for (i=0 ; i<n ; i++) {
|
||||||
item = deque_pop(deque, NULL);
|
item = deque_pop(deque, NULL);
|
||||||
|
@ -280,7 +287,7 @@ deque_rotate(dequeobject *deque, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(rotate_doc,
|
PyDoc_STRVAR(rotate_doc,
|
||||||
"Rotate the deque n steps to the right. If n is negative, rotates left.");
|
"Rotate the deque n steps to the right (default n=1). If n is negative, rotates left.");
|
||||||
|
|
||||||
static int
|
static int
|
||||||
deque_len(dequeobject *deque)
|
deque_len(dequeobject *deque)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue