-1

Not sure where I picked this up, but it stuck and I use it all the time.

Can someone explain how this string reversal works? I use it to test for palindromic strings without converting it to a mutable type first.

>>> word = "magic"
>>> magic = word[::-1]
>>> magic
'cigam' 

I would put my best guess, but I don't want to walk in with any preconceptions about the internals behind this useful trick.

Marcin
  • 48,559
  • 18
  • 128
  • 201
yurisich
  • 6,991
  • 7
  • 42
  • 63
  • It's good you changed from "sort" to "reversal", but it's also not "in-place". The variable `string` remains the same. – David Robinson Jan 08 '12 at 20:25
  • @DavidRobinson Thank you for pointing that out. It seems my preconceptions were holding me back more so than I realized. – yurisich Jan 08 '12 at 20:32
  • you should use something like "_string" instead of "string" as your variable name, as string is a module in python. – Rusty Rob Jan 08 '12 at 20:34
  • 2
    _"The variable string remains the same."_ So, it's a invariable variable....... – eyquem Jan 08 '12 at 23:06
  • possible duplicate of [reverse a string in Python](http://stackoverflow.com/questions/766141/reverse-a-string-in-python) – yurisich Jan 09 '12 at 00:05

4 Answers4

7

The slice notation goes like this:

my_list[start:end:step]

So, when you do [::-1], it means:

  • start: nothing (default)
  • end: nothing (default)
  • step: -1 (descendent order)

So, you're going from the end of the list (default) to the first element (default), decreasing the index by one (-1).

So, as many answers said, there is no sorting nor in-place swapping, just slice notation.

juliomalegria
  • 24,229
  • 14
  • 73
  • 89
  • I did some reading...an equivalent statement would be `word[None:None:-1]`...this helped me look at my example from a couple of new angles. Thanks! – yurisich Jan 08 '12 at 20:46
4

You can have a look here - it is an extended slice.

Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
fkerber
  • 1,032
  • 9
  • 24
  • 7
    Why not? It is an official documentation that explains it better than I can (apart from copying the explanation). – fkerber Jan 08 '12 at 20:20
  • 2
    Upvoted! If something is explained well in the documentation, Sharing a link just avoids rework. – Krishna Bharadwaj Jan 08 '12 at 20:22
  • @KrishnaBharadwaj I disagree. Here's the quote: *Negative values also work to make a copy of the same list in reverse order*. I already understand this...I would like to know more. An example goes a long way toward helping me understand the process python goes through to produce this answer. – yurisich Jan 08 '12 at 20:25
  • 2
    @Droogans: Then ask for an example. Links are perfectly acceptable answers on SO. – Ethan Furman Jan 08 '12 at 21:54
  • 1
    @EthanFurman Link-only answers are generally frowned upon, see [this meta post](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers). – Dave Newton Jan 11 '12 at 14:38
3

"What's New in Python 2.3", section 15, "Extended Slices".

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
2

This "trick" is just a particular instance of applying a slice operation to a sequence. You can use it to produce a reversed copy of a list or a tuple as well. Another "trick" from the same family: [:] is often used to produce a (shallow) copy of a list.

"What's new in Python 2.3" is an unexpected entry point into the maze. Let's start at a more obvious(?) place, the current 2.X documentation for sequence objects.

In the table of sequence operations, you'll see a row with Operation = s[i:j:k], Result = "slice of s from i to j with step k", and Notes = "(3)(5)".

Note 3 says "If i or j is negative, the index is relative to the end of the string: len(s) + i or len(s) + j is substituted. But note that -0 is still 0."

Note 5 says "The slice of s from i to j with step k is defined as the sequence of items with index x = i + n*k such that 0 <= n < (j-i)/k. In other words, the indices are i, i+k, i+2*k, i+3*k and so on, stopping when j is reached (but never including j). If i or j is greater than len(s), use len(s). If i or j are omitted or None, they become “end” values (which end depends on the sign of k). Note, k cannot be zero. If k is None, it is treated like 1."

We have k == -1, so the indices used are i, i-1, i-2, i-3 and so on, stopping when j is reached (but never including j). To obtain the observed effect, the "end" value used for i must be len(s)-1, and the "end" value used for j must be -1. Thus the indices used are last, last-1, ..., 2, 1.

Another entry point is to consider how we might produce such a result for any sequence if [::-1] didn't exist in the language:

def reverse_traversal_of_sequence(s):
    for x in range(len(s) - 1, -1, -1):
        do_something_with(s[x])
John Machin
  • 81,303
  • 11
  • 141
  • 189