7
s="google"
print("".join(reversed(s)))  //elgoog
print(s[::-1])  //elgoog

In above the string is reverse using python 3 reversed method and slicing method both display the same output, but from this which one is most efficient in python programming language, why??

Mazdak
  • 105,000
  • 18
  • 159
  • 188
sridhar pv
  • 134
  • 2
  • 13

2 Answers2

6

When you talk about efficiency you should specify from which perspective? Memory, Runtime, Implementation, etc.

Regard the runtime the reverse indexing is definitely faster because when you use join plus reversed you're calling two functions which both has their own deficiencies (suspending and resuming a function's frame, etc.) compare to a simple indexing. But if you want to loop over the character one by one, for any purpose, and the memory is an issue (mostly when the string is large) you can use reversed because it returns an iterator object.

In [2]: s = "example"

In [4]: r = reversed(s)

In [5]: next(r)  # e.g. You can access to the characters using `next()`
Out[5]: 'e'

So the conclusion is that you should choose the method based on your need and actually this is why there are multiple ways for one particular task in Python.

Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • 2
    @jpp I believe wim's comment applies *after* the `str.join` call – Chris_Rands Jun 25 '18 at 14:49
  • 2
    @jpp ``reversed`` does *not* copy the string, it *iterates* in reverse. There is never a copy made. In contrast, ``s[::1]`` does create a copy. That's why the use case is critical to decide what is most efficient. – MisterMiyagi Jun 25 '18 at 14:50
  • @Chris_Rands, Thank you, this makes more sense. `reversed`, as an iterator, doesn't copy the entire string. Thanks! – jpp Jun 25 '18 at 14:51
  • `''.join(...)` is not slower because of "calling two functions". It's slower because of iteration within Python runtime. – wim Jun 25 '18 at 16:04
  • @wim Yes, that too. But using those two functions has its own noticeable overhead as well. Also, note that iterations at either C or Python level both make the program slow (increase the complexity) but what's important is the amount of codes/interpretations that's happening at Python level which in this case creating/interpreting/etc. a function twice has enough overhead to make your code slower. – Mazdak Jun 25 '18 at 17:42
2

There is no significant difference in memory efficiency. Since strings are immutable, both approaches must copy the entire data.

To check performance, you can use the timeit module in standard libraries. Slicing is significantly faster, due to avoiding iteration within Python code:

>>> s = "google"
>>> %timeit "".join(reversed(s))
612 ns ± 20.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
>>> %timeit s[::-1]
157 ns ± 3.96 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

And the runtime improvement is increasing for larger strings:

>>> s = s*1000
>>> %timeit "".join(reversed(s))
119 µs ± 2.37 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit s[::-1]
10.8 µs ± 123 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

CPython 3.7.0b4 on macOS.

wim
  • 338,267
  • 99
  • 616
  • 750