Reversing a string

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Scott

    #1

    Reversing a string

    Yeah I know strings == immutable, but question 1 in section 7.14 of "How to
    think like a computer Scientist" has me trying to reverse one.

    I've come up with two things, one works almost like it should except that
    every traversal thru the string I've gotten it to repeat the "list" again.
    This is what it looks like:

    Code:
    [QUOTE][QUOTE][QUOTE]
    >>>mylist = []
    >>>def rev(x):[/QUOTE][/QUOTE][/QUOTE]
    for char in x:
    mylist.append(char)
    mylist.reverse()
    print mylist
    And the output that sorta works like it should, but threw a curveball, at me
    looks like this:
    >>rev("this is just a test")
    ['t']
    ['h', 't']
    ['i', 't', 'h']
    ['s', 'h', 't', 'i']
    [' ', 'i', 't', 'h', 's']
    ['i', 's', 'h', 't', 'i', ' ']
    ['s', ' ', 'i', 't', 'h', 's', 'i']
    [' ', 'i', 's', 'h', 't', 'i', ' ', 's']
    ['j', 's', ' ', 'i', 't', 'h', 's', 'i', ' ']
    ['u', ' ', 'i', 's', 'h', 't', 'i', ' ', 's', 'j']
    ['s', 'j', 's', ' ', 'i', 't', 'h', 's', 'i', ' ', 'u']
    ['t', 'u', ' ', 'i', 's', 'h', 't', 'i', ' ', 's', 'j', 's']
    [' ', 's', 'j', 's', ' ', 'i', 't', 'h', 's', 'i', ' ', 'u', 't']
    ['a', 't', 'u', ' ', 'i', 's', 'h', 't', 'i', ' ', 's', 'j', 's', ' ']
    [' ', ' ', 's', 'j', 's', ' ', 'i', 't', 'h', 's', 'i', ' ', 'u', 't', 'a']
    ['t', 'a', 't', 'u', ' ', 'i', 's', 'h', 't', 'i', ' ', 's', 'j', 's', ' ',
    ' ']
    ['e', ' ', ' ', 's', 'j', 's', ' ', 'i', 't', 'h', 's', 'i', ' ', 'u', 't',
    'a', 't']
    ['s', 't', 'a', 't', 'u', ' ', 'i', 's', 'h', 't', 'i', ' ', 's', 'j', 's',
    ' ', ' ', 'e']
    ['t', 'e', ' ', ' ', 's', 'j', 's', ' ', 'i', 't', 'h', 's', 'i', ' ', 'u',
    't', 'a', 't', 's']


    So I figured maybe make it a generator (I'm not TO familiar with generators
    yet so don't laugh) which changed my code just a slight bit:

    Code:
    [QUOTE][QUOTE][QUOTE]
    >>>mylist = []
    >>>def rev(x):[/QUOTE][/QUOTE][/QUOTE]
    for char in x:
    mylist.append(char)
    mylist.reverse()
    yield mylist
    But even that threw me a curveball:
    >>rev("this is just a test")
    <generator object at 0x00D52170>

    So how on earth would be the best way to: Write a function that takes a
    string as an argument and outputs the letters backward, one per line.

    It should look like the first char of every list in the top "working" code.

    Any help woould be greatly apreciated, and a little bit of explaination as
    to why you did it the way you did would be more helpful than just the code.

    Thanks in advance


  • Stefan Behnel

    #2
    Re: Reversing a string

    Scott wrote:
    So how on earth would be the best way to: Write a function that takes a
    string as an argument and outputs the letters backward, one per line.
    Homework?

    Anyway, what about:

    for c in string[::-1]:
    print c


    Stefan

    Comment

    • Will Maier

      #3
      Re: Reversing a string

      On Wed, Jun 27, 2007 at 12:53:36PM -0400, Scott wrote:
      So how on earth would be the best way to: Write a function that
      takes a string as an argument and outputs the letters backward,
      one per line.
      >>def rev(forward):
      ... backward = list(forward)
      ... backward.revers e()
      ... return ''.join(backwar d)
      >>rev("spam")
      'maps'

      list.reverse() changes the list in-place. Instead of iterating over
      the items in the string sequence, you can just convert the input
      string outright.

      --

      [Will Maier]-----------------[willmaier@ml1.n et|http://www.lfod.us/]

      Comment

      • Diez B. Roggisch

        #4
        Re: Reversing a string

        Scott wrote:
        Code:
        [QUOTE][QUOTE]
        >>>>mylist = []
        >>>>def rev(x):
        Yeah I know strings == immutable, but question 1 in section 7.14 of "How to think like a computer Scientist" has me trying to reverse one. > I've come up with two things, one works almost like it should except that every traversal thru the string I've gotten it to repeat the "list" again. This is what it looks like: >
        [/QUOTE] for char in x: mylist.append(char) mylist.reverse() print mylist
        [/QUOTE]

        <snip/>

        The reverse() is totally useless to apply each when appending each
        character. Not only useless, but faulty: if you have a even number of
        characters, your string won't be reversed.

        All you need to do is this:
        >>x = "abcdefg"
        >>print "".join(reverse d(x))
        gfedcba


        HTH Diez

        Comment

        • Terry Reedy

          #5
          Re: Reversing a string


          "Scott" <s_broscious@co mcast.netwrote in message
          news:cYWdncuhLL 6PCx_bnZ2dnUVZ_ o2vnZ2d@comcast .com...
          | Yeah I know strings == immutable, but question 1 in section 7.14 of "How
          to
          | think like a computer Scientist" has me trying to reverse one.
          >>'this is a test'[::-1]
          'tset a si siht'



          Comment

          • Neil Cerutti

            #6
            Re: Reversing a string

            On 2007-06-27, Scott <s_broscious@co mcast.netwrote:
            Yeah I know strings == immutable, but question 1 in section
            7.14 of "How to think like a computer Scientist" has me trying
            to reverse one.
            No, it just wants to to print the characters in reverse, one per
            line.
            I've come up with two things, one works almost like it should
            except that every traversal thru the string I've gotten it to
            repeat the "list" again. This is what it looks like:
            >
            >>>>mylist = []
            That's bad. If you need to use a list in the rev function, you
            should bind a new list to a local variable inside rev.
            >>>>def rev(x):
            for char in x:
            mylist.append(c har)
            mylist.reverse( )
            print mylist
            Here's an debugging exercise that you should try.

            Please explain what you think each line in the above is supposed
            to do. Pretend you are trying to convince me that the above
            program works correctly. I bet you will see find your errors
            right away as a result of this exercise.
            [/code]
            So I figured maybe make it a generator (I'm not TO familiar
            with generators yet so don't laugh) which changed my code just
            a slight bit:
            Experimentation with stuff you don't fully understand is a great
            way to learn, but not that useful for solving exercises. ;)

            --
            Neil Cerutti
            This team is one execution away from being a very good basketball team. --Doc
            Rivers

            Comment

            • ptn

              #7
              Re: Reversing a string

              >>>mylist = []
              >
              That's bad. If you need to use a list in the rev function, you
              should bind a new list to a local variable inside rev.
              >
              He's right. If you want to use a list to temporarily store the
              reversed version of your string, it should exist only in the local
              namespace of your function.

              There's still stuff you can do with your function to make it work,
              such as:
              >>def rev(x):
              mylist = []
              for char in x:
              mylist.append(c har)
              mylist.reverse( )
              for letter in mylist:
              print letter

              However, compare the incredible difference in clarity and elegance
              between that and:
              >print "\n".join("spam "[::-1])
              So, big lessons: (1) Global variables suck if you try to manipulate
              them and (2) in Python, if your code isn't as clear as you would like,
              there's probably a better way to do it.

              Comment

              • Martin Durkin

                #8
                Re: Reversing a string

                ptn <tn.pablo@gmail .comwrote in news:1182997438 .541012.54100
                @o61g2000hsh.go oglegroups.com:
                >
                >>>def rev(x):
                mylist = []
                for char in x:
                mylist.append(c har)
                mylist.reverse( )
                for letter in mylist:
                print letter
                >
                However, compare the incredible difference in clarity and elegance
                between that and:
                >
                >>print "\n".join("spam "[::-1])
                >
                OK, maybe I'm missing the point here as I'm new to Python. The first one
                seems clearer to me. What am I missing?

                Martin

                Comment

                • Duncan Booth

                  #9
                  Re: Reversing a string

                  Martin Durkin <nospam@william sdurkin.co.ukwr ote:
                  >>>>def rev(x):
                  > mylist = []
                  > for char in x:
                  > mylist.append(c har)
                  > mylist.reverse( )
                  > for letter in mylist:
                  > print letter
                  >>
                  >However, compare the incredible difference in clarity and elegance
                  >between that and:
                  >>
                  >>>print "\n".join("spam "[::-1])
                  >>
                  >
                  OK, maybe I'm missing the point here as I'm new to Python. The first one
                  seems clearer to me. What am I missing?
                  >
                  I think all you are missing is familarity with Python, but I too don't like
                  one-liners simply for their own sake.

                  Slicing is one of Pythons great features, but even experienced programmers
                  often forget that you can have a third argument to a slice or that it can
                  even be negative.

                  The syntax for joining a sequence of strings with a separator is ugly, I
                  sometimes prefer to write it out as:
                  print str.join('\n', whatever)
                  or:
                  joinlines = '\n'.join
                  ...
                  print joinlines(whate ver)

                  but in this case I'd be as likely to go for an explicit loop for the print:

                  def rev(x):
                  for letter in x[::-1]:
                  print letter

                  which I think hits about the optimum between brevity and clarity. Your own
                  optimum point may of course vary.

                  Comment

                  • Martin Durkin

                    #10
                    Re: Reversing a string

                    Duncan Booth <duncan.booth@i nvalid.invalidw rote in
                    news:Xns996067A FF71DDduncanboo th@127.0.0.1:
                    Martin Durkin <nospam@william sdurkin.co.ukwr ote:
                    >
                    >>>>>def rev(x):
                    >> mylist = []
                    >> for char in x:
                    >> mylist.append(c har)
                    >> mylist.reverse( )
                    >> for letter in mylist:
                    >> print letter
                    >>>
                    >>However, compare the incredible difference in clarity and elegance
                    >>between that and:
                    >>>
                    >>>>print "\n".join("spam "[::-1])
                    >>>
                    >>
                    >OK, maybe I'm missing the point here as I'm new to Python. The first
                    >one seems clearer to me. What am I missing?
                    >>
                    I think all you are missing is familarity with Python, but I too don't
                    like one-liners simply for their own sake.
                    >
                    I guess that's it. The first one reads more like a textbook example which
                    is about where I am at. Is there any speed benefit from the one liner?
                    thanks
                    Martin

                    Comment

                    • Stefan Behnel

                      #11
                      Re: Reversing a string

                      Martin Durkin wrote:
                      Duncan Booth <duncan.booth@i nvalid.invalidw rote in
                      news:Xns996067A FF71DDduncanboo th@127.0.0.1:
                      >
                      >Martin Durkin <nospam@william sdurkin.co.ukwr ote:
                      >>
                      >>>>>>def rev(x):
                      >>> mylist = []
                      >>> for char in x:
                      >>> mylist.append(c har)
                      >>> mylist.reverse( )
                      >>> for letter in mylist:
                      >>> print letter
                      >>>>
                      >>>However, compare the incredible difference in clarity and elegance
                      >>>between that and:
                      >>>>
                      >>>>>>>print "\n".join("spam "[::-1])
                      >>OK, maybe I'm missing the point here as I'm new to Python. The first
                      >>one seems clearer to me. What am I missing?
                      >>>
                      >I think all you are missing is familarity with Python, but I too don't
                      >like one-liners simply for their own sake.
                      >>
                      >
                      I guess that's it. The first one reads more like a textbook example which
                      is about where I am at. Is there any speed benefit from the one liner?
                      Almost definitely. But you can check yourself by using the timeit module.

                      Stefan

                      Comment

                      • Evan Klitzke

                        #12
                        Re: Reversing a string

                        On 1 Jul 2007 11:09:40 GMT, Martin Durkin <nospam@william sdurkin.co.ukwr ote:
                        Duncan Booth <duncan.booth@i nvalid.invalidw rote in
                        news:Xns996067A FF71DDduncanboo th@127.0.0.1:
                        >
                        Martin Durkin <nospam@william sdurkin.co.ukwr ote:
                        >>>>def rev(x):
                        > mylist = []
                        > for char in x:
                        > mylist.append(c har)
                        > mylist.reverse( )
                        > for letter in mylist:
                        > print letter
                        >>
                        >However, compare the incredible difference in clarity and elegance
                        >between that and:
                        >>
                        >>>print "\n".join("spam "[::-1])
                        >>
                        >
                        OK, maybe I'm missing the point here as I'm new to Python. The first
                        one seems clearer to me. What am I missing?
                        >
                        I think all you are missing is familarity with Python, but I too don't
                        like one-liners simply for their own sake.
                        >
                        I guess that's it. The first one reads more like a textbook example which
                        is about where I am at. Is there any speed benefit from the one liner?
                        The one line is quite a bit faster:

                        evan@thinkpad ~ $ python -m timeit 's = "onomatopoe ia"; s = s.join(s[::-1])'
                        100000 loops, best of 3: 6.24 usec per loop

                        evan@thinkpad ~ $ python -m timeit '
                        def rev(x):
                        mylist = []
                        for char in x:
                        mylist.append(c har)
                        mylist.reverse( )
                        return "".join(myl ist)
                        >
                        s = "onomatopoe ia"
                        s = rev(s)'
                        100000 loops, best of 3: 9.73 usec per loop

                        --
                        Evan Klitzke <evan@yelp.co m>

                        Comment

                        • Alex Martelli

                          #13
                          Re: Reversing a string

                          Jay Loden <python@jaylode n.comwrote:
                          ...
                          For what it's worth, with python 2.5 on my Macbook:
                          Hmmm, doesn't look to me as if it's worth much...:
                          [jloden@macbook jloden]$ python -m timeit 's = "onomatopoe ia"; s =
                          s.join(s[::-1])'

                          since what you're doing is...:
                          >>s = "onomatopoe ia"
                          >>s = s.join(s[::-1])
                          >>s
                          'aonomatopoeiai onomatopoeiaeon omatopoeiaoonom atopoeiaponomat opoeiaoonoma
                          topoeiatonomato poeiaaonomatopo eiamonomatopoei aoonomatopoeian onomatopoeia
                          o'
                          >>>
                          ....which isn't really just reversing the string, but quite a bit more
                          work!-)


                          Alex

                          Comment

                          • Frank Swarbrick

                            #14
                            Re: Reversing a string

                            Alex Martelli wrote:
                            Martin Durkin <nospam@william sdurkin.co.ukwr ote:
                            ...
                            >>>>>>>>print "\n".join("spam "[::-1])
                            ...
                            >>>OK, maybe I'm missing the point here as I'm new to Python. The first
                            >>>one seems clearer to me. What am I missing?
                            >>>>
                            >>I think all you are missing is familarity with Python, but I too don't
                            >>like one-liners simply for their own sake.
                            >I guess that's it. The first one reads more like a textbook example which
                            >is about where I am at. Is there any speed benefit from the one liner?
                            >
                            The first example reads "excruciati ngly low-level" to me: its autor is
                            thinking in terms of what the machine is doing, mapped into pretty
                            elementary low-level constructs.
                            >
                            The second example depends first of all on knowledge of extended-slicing
                            (specifically the fact that x[::-1] is a reversal, because of the
                            negative -1 "step" aka "stride"). If you don't know about extended
                            slicing, you're unlikely to just "get it from context", because it uses
                            a syntax based on punctuation rather than readable words whose meaning
                            you might guess at. Python has a modest amount of such "punctuatio n
                            syntax" -- about the same amount as C but definitely more than Cobol
                            (where one would typically write "ADD a TO b" to avoid shocking totally
                            clueless readers with "mysterious punctuation" such as "a + b"...!!!-).
                            Punctuation is often very concise but not "intrinsica lly obvious" unless
                            you've been exposed to it already;-).
                            Since you mentioned Cobol I couldn't resist...

                            move "spam" to spam
                            Display Function Reverse(spam)

                            There's also slicing (known in Cobol as "reference modification")
                            move mystring(5:3) to my-newstring
                            * moves 3 characters starting with character 5

                            No "negative" slicing, though it could be simulated with Function
                            Reverse() and ref.mod.

                            Frank

                            Comment

                            • Jay Loden

                              #15
                              Re: Reversing a string


                              Alex Martelli wrote:
                              since what you're doing is...:
                              >
                              >>>s = "onomatopoe ia"
                              >>>s = s.join(s[::-1])
                              >>>s
                              'aonomatopoeiai onomatopoeiaeon omatopoeiaoonom atopoeiaponomat opoeiaoonoma
                              topoeiatonomato poeiaaonomatopo eiamonomatopoei aoonomatopoeian onomatopoeia
                              o'
                              >
                              ...which isn't really just reversing the string, but quite a bit more
                              work!-)
                              That's what I get for copying and pasting from the post preceding mine and not actually checking it for what it does ;)

                              Comment

                              Working...