invert or reverse a string... warning this is a rant

Discussion in 'Python' started by rick, Oct 19, 2006.

  1. rick

    rick Guest

    Why can't Python have a reverse() function/method like Ruby?

    Python:
    x = 'a_string'
    # Reverse the string
    print x[::-1]

    Ruby:
    x = 'a_string'
    # Reverse the string
    print x.reverse

    The Ruby approach makes sense to me as a human being. The Python
    approach is not easy for me (as a human being) to remember. Can that be
    changed or should I just start blindly memorizing this stuff?

    P.S. I like Python better than Ruby 90% of the time and use Python 90%
    of the time, but 10% of the time, little things such as this drive me crazy!
     
    rick, Oct 19, 2006
    #1
    1. Advertising

  2. rick

    John Salerno Guest

    rick wrote:
    > Why can't Python have a reverse() function/method like Ruby?


    I'm not steeped enough in daily programming to argue that it isn't
    necessary, but my question is why do you need to reverse strings? Is it
    something that happens often enough to warrant a method for it?
     
    John Salerno, Oct 19, 2006
    #2
    1. Advertising

  3. rick

    Paul Rubin Guest

    rick <> writes:
    > Why can't Python have a reverse() function/method like Ruby?
    >
    > Python:
    > x = 'a_string'
    > # Reverse the string
    > print x[::-1]
    >
    > The Ruby approach makes sense to me as a human being. The Python
    > approach is not easy for me (as a human being) to remember. Can that
    > be changed or should I just start blindly memorizing this stuff?


    You could use:

    print ''.join(reversed(x))

    That also looks a little bit weird, but it combines well-known Python
    idioms straightforwardly.
     
    Paul Rubin, Oct 19, 2006
    #3
  4. rick wrote:

    > The Ruby approach makes sense to me as a human being.


    do the humans on your planet spend a lot of time reversing strings?
    it's definitely not a very common thing to do over here.

    anyway, if you do this a lot, why not define a helper function?

    def reverse(s):
    return s[::-1]

    print reverse("redael ruoy ot em ekat")

    </F>
     
    Fredrik Lundh, Oct 19, 2006
    #4
  5. rick

    Brad Guest

    John Salerno wrote:
    > rick wrote:
    >> Why can't Python have a reverse() function/method like Ruby?

    >
    > I'm not steeped enough in daily programming to argue that it isn't
    > necessary, but my question is why do you need to reverse strings? Is it
    > something that happens often enough to warrant a method for it?


    I'm home for lunch so my email addy is different.

    No, it doesn't happen very often, but when I need to reverse something
    (usually a list or a string). I can never remember right of the top of
    my head how to do so in Python. I always have to Google for an answer or
    refer back to old code.

    IMO, I should be able to intuitively know how to do this. Python is so
    user-friendly most every place else... why can it not be so here?

    I wrote this so I'll never have to remember this again:

    def invert(invertable_object):
    try:
    print invertable_object[::-1]
    return invertable_object[::-1]
    except:
    print 'Object not invertable'
    return 1

    invert([1,2,3,4])
    invert('string')
    invert({1:2, 3:4})
     
    Brad, Oct 19, 2006
    #5
  6. rick

    Neil Cerutti Guest

    On 2006-10-19, Brad <> wrote:
    > I'm home for lunch so my email addy is different.
    >
    > No, it doesn't happen very often, but when I need to reverse
    > something (usually a list or a string). I can never remember
    > right of the top of my head how to do so in Python. I always
    > have to Google for an answer or refer back to old code.
    >
    > IMO, I should be able to intuitively know how to do this.
    > Python is so user-friendly most every place else... why can it
    > not be so here?
    >
    > I wrote this so I'll never have to remember this again:
    >
    > def invert(invertable_object):
    > try:
    > print invertable_object[::-1]
    > return invertable_object[::-1]
    > except:
    > print 'Object not invertable'
    > return 1
    >
    > invert([1,2,3,4])
    > invert('string')
    > invert({1:2, 3:4})


    Shoot, now you'll have to remember where in heck you stashed that
    function the next time you need to reverse something. ;-)

    You'll still be better off in the long run memorizing the slice
    notation.

    --
    Neil Cerutti
     
    Neil Cerutti, Oct 19, 2006
    #6
  7. rick

    Brad Guest

    Fredrik Lundh wrote:
    > rick wrote:
    >
    >> The Ruby approach makes sense to me as a human being.

    >
    > do the humans on your planet spend a lot of time reversing strings? it's
    > definitely not a very common thing to do over here.


    On our planet, we're all dyslexic. We tend to do things 'backwards' so
    being able to easily invert what we do helps the people we show the code
    to on your planet make sense of it.

    >
    > anyway, if you do this a lot, why not define a helper function?
    >
    > def reverse(s):
    > return s[::-1]
    >
    > print reverse("redael ruoy ot em ekat")


    Thanks, that's what I ended up doing.
     
    Brad, Oct 19, 2006
    #7
  8. rick

    James Stroud Guest

    John Salerno wrote:
    > rick wrote:
    >
    >> Why can't Python have a reverse() function/method like Ruby?

    >
    >
    > I'm not steeped enough in daily programming to argue that it isn't
    > necessary, but my question is why do you need to reverse strings?


    It would provide symmetry for reversing any sequence (without requiring
    an iterator).

    (1,2,3).reversed()

    "123".reversed()

    [1,2,3].reversed()



    --
    James Stroud
    UCLA-DOE Institute for Genomics and Proteomics
    Box 951570
    Los Angeles, CA 90095

    http://www.jamesstroud.com/
     
    James Stroud, Oct 19, 2006
    #8
  9. rick

    Paul Boddie Guest

    James Stroud wrote:
    >
    > It would provide symmetry for reversing any sequence (without requiring
    > an iterator).
    >
    > (1,2,3).reversed()
    >
    > "123".reversed()
    >
    > [1,2,3].reversed()


    That might infuriate those who regard strings as "mischievous"
    sequences (ie. things which cause errors because you think you have a
    list, but you're actually accessing characters in a string), but it's a
    valid point: the built-in sequence types should, within reason, provide
    a similar interface.

    The proposed solution involving slicing syntax does seem odd in the
    sense that it's highly similar to the redundant-for-strings s[:]
    operation, and it might require inspiration for anyone looking for
    convenience methods on the string object to consider using slicing
    instead in this manner. In looking for alternative approaches, I became
    somewhat distracted by the classic approach you'd use with certain
    functional languages: convert the string into a list of characters (if
    it isn't already treated as a list), reverse the list, concatenate the
    list. The following requires Python 2.4:

    "".join(list(reversed(list(s))))

    I guess Python 2.5 has the reversed method of which you speak. Still,
    the simplest things are often the best, and Python's classic operators
    (indexing, slicing) should always be kept in mind.

    Paul
     
    Paul Boddie, Oct 19, 2006
    #9
  10. rick

    James Stroud Guest

    Paul Boddie wrote:
    > James Stroud wrote:
    >>(1,2,3).reversed()
    >>
    >>"123".reversed()
    >>
    >>[1,2,3].reversed()

    >
    > I guess Python 2.5 has the reversed method of which you speak.


    Not that I could find (as methods of any built in sequence type). 2.5
    just has the "reversed" function that returns and iterator and so 2.5
    requires these kind of gymnastics on built in sequences:

    > "".join(list(reversed(list(s))))


    Of course, I think str.join can operate on iterators, as Paul Rubin
    suggests:

    > print ''.join(reversed(x))


    This latter approach still seems a little clunky, though.

    James


    --
    James Stroud
    UCLA-DOE Institute for Genomics and Proteomics
    Box 951570
    Los Angeles, CA 90095

    http://www.jamesstroud.com/
     
    James Stroud, Oct 19, 2006
    #10
  11. rick

    Ron Adam Guest

    James Stroud wrote:

    > Of course, I think str.join can operate on iterators, as Paul Rubin
    > suggests:
    >
    > > print ''.join(reversed(x))

    >
    > This latter approach still seems a little clunky, though.
    >
    > James


    Slices can be named so you could do...

    >>> reverser = slice(None, None, -1)
    >>>
    >>> 'abcdefg'[reverser]

    'gfedcba'


    Ron
     
    Ron Adam, Oct 19, 2006
    #11
  12. James Stroud wrote:

    > without requiring an iterator


    can we perhaps invent some more arbitrary constraints while we're at it?

    </F>
     
    Fredrik Lundh, Oct 19, 2006
    #12
  13. rick

    James Stroud Guest

    Fredrik Lundh wrote:
    > James Stroud wrote:
    >
    > > without requiring an iterator

    >
    > can we perhaps invent some more arbitrary constraints while we're at it?
    >
    > </F>
    >


    Why does it seem to me that you are confusing convienience with
    constraint, or are the two equivalent?

    James

    --
    James Stroud
    UCLA-DOE Institute for Genomics and Proteomics
    Box 951570
    Los Angeles, CA 90095

    http://www.jamesstroud.com/
     
    James Stroud, Oct 19, 2006
    #13
  14. rick

    Neil Cerutti Guest

    On 2006-10-19, Fredrik Lundh <> wrote:
    > James Stroud wrote:
    >
    > > without requiring an iterator

    >
    > can we perhaps invent some more arbitrary constraints while
    > we're at it?


    No letter G. I don't like them. They wet their nests.

    --
    Neil Cerutti
    You only get a once-in-a-lifetime opportunity so many times.
    --Ike Taylor
     
    Neil Cerutti, Oct 19, 2006
    #14
  15. rick

    James Stroud Guest

    Fredrik Lundh wrote:
    > James Stroud wrote:
    >
    > > without requiring an iterator

    >
    > can we perhaps invent some more arbitrary constraints while we're at it?
    >
    > </F>
    >


    I guess while I'm at it, this thread wouldn't have so much steam were
    these idioms seemingly unpythonic:

    "".join(reverse(x))
    alist[::-1]

    The latter, while more terse than alist.reversed(), is unnatural and
    ugly compared to the general elegance of other constructs in python.
    Were this not the case, beginners and intermediate programmers alike
    would not have such trouble remembering it. In fact, the latter's exact
    behavior, if I remember correctly, spawned a thread of its own with much
    speculation as to the exact meaning of the documentation and whether the
    API conformed to this inferred meaning. I'll attempt to provide a link
    to the thread if anyone takes me to task on this.

    I'm sure many life-long programmers will claim that they have never
    created a reverse copy of a data structure for production code, but why
    is it that so many jump to the fore to point out that alist[::-1] is how
    one produces a reverse copy of a list, or that a string can be reversed
    with reversed, join, and an instance of another string (did I leave
    something out?)?

    But why do so many beginning programmers ask how one might produce a
    reverse data structure in python? Perhaps they are just ignorant fools
    who don't know that creating a reverse copy of a data structure can be
    proven to be a useless operation if only they would stop trying to write
    code and begin to write formal proofs. Perhaps their professors are to
    blame, unreasonably asking them to write actual code before memorizing
    all three+ volumes of Knuth. I'm sure the proof is in there somewhere.

    But maybe it is not the purpose of a poweful language like python to be
    used as a teaching language. Maybe python should be reserved for use
    only by those who have been desensitized to its idiosyncracies,
    inconsistencies, and idiomatic workarounds.

    James

    --
    James Stroud
    UCLA-DOE Institute for Genomics and Proteomics
    Box 951570
    Los Angeles, CA 90095

    http://www.jamesstroud.com/
     
    James Stroud, Oct 19, 2006
    #15
  16. rick

    James Stroud Guest

    Neil Cerutti wrote:
    > On 2006-10-19, Fredrik Lundh <> wrote:
    >
    >>James Stroud wrote:
    >>
    >>
    >>>without requiring an iterator

    >>
    >>can we perhaps invent some more arbitrary constraints while
    >>we're at it?

    >
    >
    > No letter G. I don't like them. They wet their nests.
    >


    The requirement for an iterator is the constraint. Removin the
    requirement for the iterator removes the constraint. Or is the iterator
    the convenience?

    James

    --
    James Stroud
    UCLA-DOE Institute for Genomics and Proteomics
    Box 951570
    Los Angeles, CA 90095

    http://www.jamesstroud.com/
     
    James Stroud, Oct 19, 2006
    #16
  17. rick

    Guest

    James> I guess while I'm at it, this thread wouldn't have so much steam
    James> were these idioms seemingly unpythonic:

    James> "".join(reverse(x))
    James> alist[::-1]

    James> The latter, while more terse than alist.reversed(), is unnatural
    James> and ugly compared to the general elegance of other constructs in
    James> python. Were this not the case, beginners and intermediate
    James> programmers alike would not have such trouble remembering it.

    I've no comment one way or the other on the "".join() idiom. I realize a
    lot of folks don't like it. The extended slice notation comes from the
    numeric community though where they are probably all former FORTRAN
    programmers. I think the concept of start, stop, step (or stride?) is
    pretty common there. It also fairly nicely matches the arguments to range()
    and extends the list "copy operator" alist[:] in a more-or-less
    straightforward fashion. It takes a little getting used to, but it's really
    not all that hard to remember once you've seen it a couple times. Besides,
    it's not obvious to me that simple sequence slicing would be all that
    familiar to the uninitiated.

    go-bruins-ly, y'rs,

    Skip
     
    , Oct 19, 2006
    #17
  18. On Thu, 19 Oct 2006 12:38:55 -0400, Brad wrote:

    > John Salerno wrote:
    >> rick wrote:
    >>> Why can't Python have a reverse() function/method like Ruby?

    >>
    >> I'm not steeped enough in daily programming to argue that it isn't
    >> necessary, but my question is why do you need to reverse strings? Is it
    >> something that happens often enough to warrant a method for it?

    >
    > I'm home for lunch so my email addy is different.
    >
    > No, it doesn't happen very often, but when I need to reverse something
    > (usually a list or a string). I can never remember right of the top of
    > my head how to do so in Python. I always have to Google for an answer or
    > refer back to old code.
    >
    > IMO, I should be able to intuitively know how to do this. Python is so
    > user-friendly most every place else... why can it not be so here?


    I agree -- the reversed() function appears to be an obvious case of purity
    overriding practicality :(

    >>> str(reversed("some string"))

    '<reversed object at 0xb7edca4c>'
    >>> repr(reversed("some string"))

    '<reversed object at 0xb7edca4c>'

    Not very useful.

    The simplest ways to get a reversed string seem to be:

    >>> "some string"[::-1]

    'gnirts emos'
    >>> ''.join(list(reversed("some string")))

    'gnirts emos'

    neither of which are exactly intuitive, but both are standard Python
    idioms.



    > I wrote this so I'll never have to remember this again:
    >
    > def invert(invertable_object):
    > try:
    > print invertable_object[::-1]
    > return invertable_object[::-1]
    > except:
    > print 'Object not invertable'
    > return 1


    Gah!!! That's *awful* in so many ways.

    (1) The name is bad. "invert" is not the same as "reverse". Here's an
    invert: 1/2 = 0.5. Your function falsely claims numbers aren't invertable.

    (2) Why calculate the reversed object twice?

    (3) It is poor practice to have the same function both *print* the result
    and *return* the result. What happens when you want the reversed object,
    but you don't want it to print? You either write a new function, or you
    muck about capturing output and hiding it. You should return the result,
    and leave it up to the caller to print if they want to print.

    (That's a complaint I have about the dis module -- it prints its results,
    instead of returning them as a string. That makes it hard to capture the
    output for further analysis.)

    (4) Why are you capturing Python's perfectly good and useful traceback,
    and printing an unhelpful error message?

    (5) Errors should raise exceptions, not return "magic numbers" like 1. 1
    is not an error-state, it is perfectly fine output. Now you have to
    remember that your invert function returns 1 on error, and calling code
    has to check for it:

    list_of_reversed_object = []
    for obj in list_of_objects_to_reverse:
    temp = invert(obj)
    if temp == 1:
    raise ValueError("invalid object")
    # or do something else...
    list_of_reversed_objects.append(temp)

    Compare:

    list_of_reversed_object = []
    for obj in list_of_objects_to_reverse:
    list_of_reversed_objects.append(invert(obj))


    Or if you want to skip invalid objects:

    list_of_reversed_object = []
    for obj in list_of_objects_to_reverse:
    try:
    list_of_reversed_objects.append(invert(obj))
    except SomeError:
    pass



    --
    Steven.
     
    Steven D'Aprano, Oct 20, 2006
    #18
  19. rick

    Paul Rubin Guest

    Steven D'Aprano <> writes:
    > >>> ''.join(list(reversed("some string")))

    > 'gnirts emos'


    ''.join(reversed('some string')) should work, without building the
    intermediate list.

    I generally don't remember the ::-1 syntax so the above would occur to
    me sooner.
     
    Paul Rubin, Oct 20, 2006
    #19
  20. rick

    Brad Guest

    Steven D'Aprano wrote:

    > Gah!!! That's *awful* in so many ways.


    Thanks... I'm used to hearing encouragement like that. After a while you
    begin to believe that everything you do will be awful, so why even
    bother trying?

    <rant>

    It has been my experience that Python has discouraging forums with
    someone always calling someone else an idiot or telling them they are
    awful in some way. I love Python, but the community is way too negative,
    uptight and generally down on users who do not have PhD's in CS or Math.

    Do you have children? How would your child feel if he brought you
    something he had made and you then told him it was awful in *sooo* many
    ways. How does that reflect on you and the community you represent?

    Cut people who don't think like you some slack, OK?

    </rant>

    > (1) The name is bad. "invert" is not the same as "reverse". Here's an
    > invert: 1/2 = 0.5. Your function falsely claims numbers aren't invertable.


    Dictionary.com
    invert = to reverse in position, order, direction, or relationship.

    It matters not that a sequence is thought of as being from left to
    right, top to bottom or right to left, does it? Read the sequence as you
    normally would (however that may be) and then invert it or read it in
    reverse to begin with.

    I apologize for bringing this up. Thanks for your time.
     
    Brad, Oct 20, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. dogbite
    Replies:
    4
    Views:
    728
    osmium
    Oct 10, 2003
  2. rtilley

    invert the order of a string

    rtilley, Feb 13, 2006, in forum: Python
    Replies:
    10
    Views:
    9,805
    Bruno Desthuilliers
    Feb 14, 2006
  3. Demel, Jeff
    Replies:
    7
    Views:
    287
    Carl Banks
    Oct 20, 2006
  4. Demel, Jeff
    Replies:
    3
    Views:
    296
    Duncan Booth
    Oct 20, 2006
  5. Tim Chase
    Replies:
    3
    Views:
    246
    Simon Forman
    Oct 20, 2006
Loading...

Share This Page