Brandon Oson
Brandon Oson

Reputation: 11

Reversing the order

I'm new to python and not really good with recursion so if some kindly help me with this problem, it will be greatly appreciated. So I'm basically trying to reverse the order of the string. For example, if the string is" It's me" it should return "me It's". Although, I'm getting a completely reversed string and for most part I'm getting an error saying the second function is not defined.

def reverse_phrase(str):
    reverse_phrase_recursive(str.split())

def reverse_phrase_recursive(str):
    if len(str)==0:
        return str
    else:
        return reverse_phrase(str[1:]) + str[0]
        
print(reverse_phrase("DO I CHOOSE YOU PIKACHU"))

Upvotes: 2

Views: 167

Answers (6)

Mulan
Mulan

Reputation: 135207

Here's another way that doesn't rely on built-in function .split -

def reverse_phrase(s):
  def loop(s, word, phrase):
    if not s:
      return word + " " + phrase                #1
    elif s[0] == " ":
      return loop(s[1:], "", word + " " + phrase) #2
    else:
      return loop(s[1:], word + s[0], phrase)       #3
  return loop(s, "", "")

print(reverse_phrase("DO I CHOOSE YOU PIKACHU"))

Evaluates as -

loop("DO I CHOOSE YOU PIKACHU", "", "")             #3
loop("O I CHOOSE YOU PIKACHU", "D", "")             #3
loop(" I CHOOSE YOU PIKACHU", "DO", "")           #2
loop("I CHOOSE YOU PIKACHU", "", "DO ")             #3
loop(" CHOOSE YOU PIKACHU", "I", "DO ")           #2
loop("CHOOSE YOU PIKACHU", "", "I DO ")             #3
loop("HOOSE YOU PIKACHU", "C", "I DO ")             #3
loop("OOSE YOU PIKACHU", "CH", "I DO ")             #3
loop("OSE YOU PIKACHU", "CHO", "I DO ")             #3
loop("SE YOU PIKACHU", "CHOO", "I DO ")             #3
loop("E YOU PIKACHU", "CHOOS", "I DO ")             #3
loop(" YOU PIKACHU", "CHOOSE", "I DO ")           #2
loop("YOU PIKACHU", "", "CHOOSE I DO ")             #3 
loop("OU PIKACHU", "Y", "CHOOSE I DO ")             #3
loop("U PIKACHU", "YO", "CHOOSE I DO ")             #3
loop(" PIKACHU", "YOU", "CHOOSE I DO ")           #2
loop("PIKACHU", "", "YOU CHOOSE I DO ")             #3
loop("IKACHU", "P", "YOU CHOOSE I DO ")             #3
loop("KACHU", "PI", "YOU CHOOSE I DO ")             #3
loop("ACHU", "PIK", "YOU CHOOSE I DO ")             #3
loop("CHU", "PIKA", "YOU CHOOSE I DO ")             #3
loop("HU", "PIKAC", "YOU CHOOSE I DO ")             #3
loop("U", "PIKACH", "YOU CHOOSE I DO ")             #3
loop("", "PIKACHU", "YOU CHOOSE I DO ")         #1
"PIKACHU YOU CHOOSE I DO "

I think it's important not to get stuck thinking about the problem in just one way. Try to do it different ways -

def rev(s, pos = 0):
  if pos >= len(s):
    return s                              #1
  elif s[pos] == " ":
    return rev(s[pos+1:]) + " " + s[0:pos]  #2
  else:
    return rev(s, pos + 1)                    #3

print(rev("DO I CHOOSE YOU PIKACHU"))

Evaluates as -

rev("DO I CHOOSE YOU PIKACHU", 0)                    #3
rev("DO I CHOOSE YOU PIKACHU", 1)                    #3
rev("DO I CHOOSE YOU PIKACHU", 2)                  #2
rev("I CHOOSE YOU PIKACHU", 0) + " " + "DO"          #3
rev("I CHOOSE YOU PIKACHU", 1) + " DO"             #2
rev("CHOOSE YOU PIKACHU", 0) + " " + "I" + " DO"     #3
rev("CHOOSE YOU PIKACHU", 1) + " I DO"               #3
rev("CHOOSE YOU PIKACHU", 2) + " I DO"               #3
rev("CHOOSE YOU PIKACHU", 3) + " I DO"               #3
rev("CHOOSE YOU PIKACHU", 4) + " I DO"               #3
rev("CHOOSE YOU PIKACHU", 5) + " I DO"               #3
rev("CHOOSE YOU PIKACHU", 6) + " I DO"             #2                
rev("YOU PIKACHU", 0) + " " + "CHOOSE" + " I DO"     #3
rev("YOU PIKACHU", 1) + " CHOOSE I DO"               #3
rev("YOU PIKACHU", 2) + " CHOOSE I DO"               #3
rev("PIKACHU", 0) + " " + "YOU" + " CHOOSE I DO"   #2
rev("PIKACHU", 1) + " YOU CHOOSE I DO"               #3
rev("PIKACHU", 2) + " YOU CHOOSE I DO"               #3
rev("PIKACHU", 3) + " YOU CHOOSE I DO"               #3
rev("PIKACHU", 4) + " YOU CHOOSE I DO"               #3
rev("PIKACHU", 5) + " YOU CHOOSE I DO"               #3
rev("PIKACHU", 6) + " YOU CHOOSE I DO"               #3
rev("PIKACHU", 7) + " YOU CHOOSE I DO"           #1
"PIKACHU" + " YOU CHOOSE I DO"
"PIKACHU YOU CHOOSE I DO"

There's infinite ways to express a program -

def find(s, char, ifmatch, nomatch):
  def loop(pos):
    if pos >= len(s):
      return nomatch()
    elif s[pos] == char:
      return ifmatch(pos)
    else:
      return loop(pos+1)
  return loop(0)

def cut(s, char, ifmatch, nomatch):
  return find \
    ( s
    , char
    , lambda pos: ifmatch(s[0:pos], s[pos+1:])
    , lambda: nomatch(s)
    )

def rev(s):
  return cut \
    ( s
    , " "
    , lambda left, right: rev(right) + " " + left
    , lambda last: last
    )

print(rev("DO I CHOOSE YOU PIKACHU"))

Evaluates as -

cut \
  ( "DO I CHOOSE YOU PIKACHU"s
  , " "
  , lambda left, right: rev(right) + " " + left
  , lambda last: last
  )

find \
  ( "DO I CHOOSE YOU PIKACHU"
  , " "
  , lambda pos: (lambda left, right: rev(right) + " " + left)("DO I CHOOSE YOU PIKACHU"[0:pos], "DO I CHOOSE YOU PIKACHU"[pos+1:])
  , lambda: (lambda last: last)("DO I CHOOSE YOU PIKACHU")
  )

loop(0)
loop(1)
loop(2)

(lambda left, right: rev(right) + " " + left) \
  ("DO I CHOOSE YOU PIKACHU"[0:2], "DO I CHOOSE YOU PIKACHU"[2+1:])

rev("I CHOOSE YOU PIKACHU") + " " + "DO"

# ...
"PIKACHU YOU CHOOSE I DO"

Upvotes: 0

pakpe
pakpe

Reputation: 5479

Here is another way to do this without using join. Your reverse_phrase() function calls the recursive function with a list of words. The base case of recursive function is when the length of the list is 2, in which case it swaps the the two words. Else, it swaps the last word of the list with the recursive output of all the initials words.

def reverse_phrase(str):
    return reverse_phrase_recursive(str.split())

def reverse_phrase_recursive(l):
    if len(l) == 2:
        return l[1] + " " + l[0]
    return l[-1] + " " + reverse_phrase_recursive(l[:-1])

print(reverse_phrase('this is a great recursive function'))
#function recursive great a is this

Upvotes: 0

Eddie D
Eddie D

Reputation: 1120

Here is a take on the recursion without having to do the whole split / join process. As I mentioned in a comment, it's expensive performance wise.


def reverse_phrase(str, reversedStr=""):
    if (len(reversedStr) == len(str)):
      return reversedStr;

    reversedStrLength = len(reversedStr);  
    index = len(str) - reversedStrLength - 1;
    reversedStr += str[index];

    return reverse_phrase(str, reversedStr);
   
        
print(reverse_phrase("DO I CHOOSE YOU PIKACHU"));

Upvotes: 0

Inputvector
Inputvector

Reputation: 1093

Here is a solution for reversing:

def reverse(s): 
    return ' '.join(s.split()[::-1])

s = "DO I CHOOSE YOU PIKACHU" 
reverse(s)

#Output: 

'PIKACHU YOU CHOOSE I DO'

Upvotes: 0

SuperStormer
SuperStormer

Reputation: 5387

You need to call reverse_phrase_recursive as the recursive call, otherwise a list will be passed to reverse_phrase and then it will try to call .split() on a list, which throws an AttributeError.

Also, actually return the value from reverse_phrase and make the value concatted to the recursive call a list because you can't concat str to a list directly.

def reverse_phrase(str):
    return " ".join(reverse_phrase_recursive(str.split()))

def reverse_phrase_recursive(str):
    if len(str)==0:
        return str
    else:
        return reverse_phrase_recursive(str[1:]) + [str[0]]
        
print(reverse_phrase("DO I CHOOSE YOU PIKACHU"))

Side Note: don't name your variable "str", it overwrites the builtin str.

Upvotes: 1

Tim Roberts
Tim Roberts

Reputation: 54698

def reverse_phrase(str):
    return ' '.join(reversed(str.split()))

Upvotes: 0

Related Questions