7

When reverse a list in Python, I usually use the array[::-1] for reversing and I know that a more common way might swap from two sides of the list. But I'm not sure the difference between these two solutions such as time complexity and space complexity.

Code for this two methods below:

def reverse(array):
    array[:] = array[::-1]


def reverse(array):
    start, end = 0, len(array)-1
    while start < end:
        array[start], array[end] = array[end], array[start]
        start += 1
        end -= 1
JoshuaW1990
  • 142
  • 1
  • 8
  • Out of topic but you can use [`reversed()`](https://docs.python.org/2/library/functions.html#reversed) built-in functions rather than `[::-1]` to iterate over reversed list. – Kruupös Jul 26 '17 at 14:41
  • 1
    You can test which method is faster by using [`timeit`](https://docs.python.org/2/library/timeit.html) and you can use [`dis`](https://docs.python.org/2/library/dis.html) module to see the bytecode of each functions you made. As a rule of thumb, go for `array[::-1]` or `list(reversed(array))` to reverse array rather than custom function. Because Built-in functions are implemented using `CPython` and therefore very optimised. You can find the sources here: [github built-in function CPython](https://github.com/python/cpython) – Kruupös Jul 26 '17 at 14:59
  • Thanks. Maybe I didn't explain it very clear. Yes, I can use `reversed` function for reversing list, but sometimes I also need to reverse something like string and the `reverse` function doesn't work for string. In this situation, I usually use `string[::-1]`, but I don't know how it works and its performance. – JoshuaW1990 Jul 26 '17 at 16:19

2 Answers2

9

In C python, assuming array is a list, the expression array[::-1] triggers the following algorithm found in function list_subscript() in the source file listobject.c

result = PyList_New(slicelength);
if (!result) return NULL;

src = self->ob_item;
dest = ((PyListObject *)result)->ob_item;
for (cur = start, i = 0; i < slicelength;
     cur += (size_t)step, i++) {
    it = src[cur];
    Py_INCREF(it);
    dest[i] = it;
}

Both time and space complexity of this piece of code are O(n) where n is the length of the list. Of course there is no suprise here.

Your function reverse() has also O(n) time complexity, the difference is that it does not use a temporary list.

The built-in C function is much faster than the pure python loop (about 10 times on my computer for a 100 elements list).

zamir
  • 2,144
  • 1
  • 11
  • 23
Gribouillis
  • 2,230
  • 1
  • 9
  • 14
2

I ran an experiment using %%timeit on Jupyter with arrays of size 100, 1000 and 10000. The time taken by array[::-1] and reverse(array)(Swapping from two ends of the list) kept increasing almost linearly. However, the time taken by Python's inbuilt reversed function stayed almost constant, and so I guess that would be the best choice.

Time Comparison