Recursive functions : Inversing word - python

I'm trying to make a simple function that inverses a string using recursion.
this is what i tried :
def inverse(ch):
if ch=='' :
return ''
else:
return ch[len(ch)]+inverse(ch[1:len(ch)-1])
print inverse('hello')
And this is what i get :
line 13, in inverse
return ch[len(ch)]+inverse(ch[1:len(ch)-1]) IndexError: string index out of range

You're indexing the string at its length, but remember that indexing is zero based so you'll have to slice at length minus 1 which is the maximum index you can safely use.
You can however choose to be oblivious of the length by using [-1] to index the last item:
def inverse(ch):
if ch=='' :
return ''
else:
return ch[-1]+inverse(ch[:-1])
print inverse('hello')
# olleh
And you also probably want to keep in mind that slicing with [::-1] provides the same result as your recursive function.

Check this:
ch[len(ch)-1]+inverse(ch[0:len(ch)-1])

You don't really need recursion here.
def inverse(chars):
char_list = list(chars)
char_list.reverse()
return ''.join(char_list)

Related

Difference between string.replace(c,'',1)) and string[1:]

So I am trying to trace a recursive function and I'm having difficulties tracing this:
I'm trying to trace a code on permutations but this confuses me:
# doesn't work
def permutations(string):
if len(string) == 1:
return string
recursive_perms = []
for c in string:
for perm in permutations(string[1:]):
recursive_perms.append(c+perm)
return set(recursive_perms)
# works
def permutations(string):
if len(string) == 1:
return string
recursive_perms = []
for c in string:
for perm in permutations(string.replace(c,'',1)):
recursive_perms.append(c+perm)
return set(recursive_perms)
I'm horrible at tracing recursion currently, and I don't know the difference between the first and second function but the 2nd one works first one doesn't. The difference is the replace. Whats the different between the replace and doing string[1:]? Is there anyway you could change the replace into string slicing?
str.replace(old, new[, count]) replaces old with new, optionally only for the first count instances
str[1:] returns a slice of str from the character at the second index until the last index, effectively returning the entire string except for it's first character.
What really happens when you call str[1:] is that you're calling str.__getitem__(slice(1, None))

writing a function that return the reversed number

I am trying to write a Python function that get a number as input and returns its reversed number as output. for example: 1234 returns 4321.
this is what I try, but it return only ''
def reverse(num):
L=[]
x=str(num)
L1=list(x)
for i in L1:
L.insert(0,i)
print 'the reversed num is:'
x=''
for i in L:
x.join(i)
return x
any ideas?
def reverse(num):
return str(num)[::-1]
or one line:
lambda x: str(x)[::-1]
Well, the easy solution is this one:
>>> int(str(1234)[::-1])
4321
Your code can be fixed by changing the part
for i in L:
x.join(i)
return x
to
for i in L:
x += i
return x
Alternatively, just replace that section by
return ''.join(L)
What was wrong with your code? Because of wrong indentation, you returned in the first iteration of the for loop. You never assigned a name to x.join(i) so the return value was lost. What you expected join to do I do not know.
First, there is an easier way by converting to string, slicing the string and converting it back to a number.
def reverse(num):
return int(str(num)[::-1])
Second, there are multiple errors in your code:
1) your return statement is in the loop, so it will return after the first iteration;
2) x does not change because x.join() creates a new string and does not modify the string x (which is immutable by the way)
3) no need to convert the string into a list since you can directly iterate over the string (for i in x: ...)
4) join() takes an iterator as an argument. No need for the second loop: return ''.join(L)
thank you all for the helpful ideas.
here is my solution:
def reverse(n):
reverse=0
while(n>0):
dig=n%10
reverse=reverse*10
reverse=reverse+dig
n=n/10
return reverse
def reverse(num)
return str(num)[::-1]
Reverse a string in Python
Other users already gave good answers. Here is a different one, for study purposes.
num = 1234
print "".join(reversed(str(num)))
# 4321
You can convert to int afterwards.

my python code is not working.....i want to find if the entered list contains duplicate items

I want to use this function to find duplicate items in my list, but this code is not working:
p = "enter a list\n"
t = raw_input(p)
def has_duplicate(t):
o = sorted(t)
i = 0
while i < len(o):
if o[i] == o[i + 1]:
print "the list has duplicates"
elif o[i] != o[i+1]:
i += 1
if i >= len(o):
print "the list has no duplicate"
It gives me an error saying has_duplicates not defined.
As #mgilson commented, your issue is you are calling the function incorrectly (has_duplicates vs has_duplicate) however...
The most straight forward way to do this is using a set and comparing len.
def has_duplicates(t):
return len(set(t)) != len(t)
If you take an iterable and wrap it in a set you will end up with only unique items. If the length of the set is the same as your original iterable then you have no duplicates. If the length is different (will always be equal to or smaller) then you have duplicates which were removed when converting to a set type.
First thing is you do list_name.sort().
Other easy way to find duplicates is
len(your_list)!=len(set(your_list))
you might be calling function has_duplicates but you have defined has_duplicate function.
try to call has_duplicate

string.find indexing in Python

I'm trying to understand why the following python code incorrectly returns the string "dining":
def remove(somestring, sub):
"""Return somestring with sub removed."""
location = somestring.find(sub)
length = len(sub)
part_before = somestring[:location]
part_after = somestring[location + length:]
return part_before + part_after
print remove('ding', 'do')
I realize the way to make the code run correctly is to add an if statement so that if the location variable returns a -1 it will simply return the original string (in this case "ding"). The code, for example, should be:
def remove(somestring, sub):
"""Return somestring with sub removed."""
location = somestring.find(sub)
if location == -1:
return somestring
length = len(sub)
part_before = somestring[:location]
part_after = somestring[location + length:]
return part_before + part_after
print remove('ding', 'do')
Without using the if statement to fix the function, the part_before variable will return the string "din". I would love to know why this happens. Reading the python documentation on string.find (which is ultimately how part_before is formulated) I see that the location variable would become a -1 because "do" is NOT found. But if the part_before variable holds all letters before the -1 index, shouldn't it be blank and not "din"? What am I missing here?
For reference, Python documentation for string.find states:
string.find(s, sub[, start[, end]])
Return the lowest index in s where the substring sub is found such that sub is wholly contained in s[start:end]. Return -1 on failure. Defaults for start and end and interpretation of negative values is the same as for slices.
string = 'ding'
string[:-1]
>>> 'din'
Using a negative number as an index in python returns the nth element from the right-hand side. Accordingly, a slice with :-1 return all but the last element of the string.
If you have a string 'ding' and you are searching for 'do', str.find() will return -1. 'ding'[:-1] is equal to 'din' and 'ding'[-1 + len(sub):] equals 'ding'[1:] which is equal to 'ing'. Putting the two together results in 'dining'. To get the right answer, try something like this:
def remove(string, sub):
index = string.find(sub)
if index == -1:
return string
else:
return string[:index] + string[index + len(sub):]
The reason that string[:-1] is not equal to the whole string is that in slicing, the first number (in this case blank so equal to None, or for our purposes equivalent to 0) is inclusive, but the second number (-1) is exclusive. string[-1] is the last character, so that character is not included.

Python String Reversal

This exercise involves a codeacademy problem to write a function which takes a string as an input and outputs the string in reverse, I've found solutions as to how to do it online, I'm just confused as to why mine doesnt work:
def reverse(c):
empty=[]
stringsize= len(c)
for x in range(stringsize):
empty[x]=c[stringsize-x]
return empty
You need to start at indexing your string from -1 through to -stringsize, and use empty.append() to add values:
for x in range(stringsize):
empty.append(c[stringsize - x - 1])
Python indexing starts at 0, making stringsize - 1 the last index. Because empty is an empty list, you cannot index into it. Using the list.append() method adds new values at the end instead.
You don't really need the stringsize reference there, because negative indices automatically are subtracted from the length for you:
for x in range(len(c)):
empty.append(c[-x-1])
Since this is supposed to return a string, not a list, you need to join the characters again at the end:
return ''.join(empty)
The easiest way to reverse a list is to use a negative slice stride:
def reverse(c):
return c[::-1]
One solution :
def reverse(c):
empty=[]
stringsize= len(c)
for x in range(stringsize):
empty.append(c[-(x+1)])
return ''.join(empty)
print reverse('string')
Another:
def reverse(c):
empty=[]
stringsize= len(c)
for x in range(stringsize):
empty.append(c[stringsize - (x+1)])
return ''.join(empty)
print reverse('string')
Using recursion:
def reverse(string,start,stop):
if start < stop - 1:
string[start],string[stop - 1] = string[stop - 1],string[start]
reverse(string,start+1, stop-1)
return ''.join(string)
print reverse(list('string'), 0, len('string'))
In Python a string is an iterable so iterable functions can be used with it. For example reversed function:
>>> "".join(reversed("123"))
'321'
The least changes necessary to make your code run seem to be:
def reverse(c):
stringsize= len(c)
empty=[None] * stringsize
for x in range(stringsize):
empty[x]=c[stringsize-x-1]
return empty
But you should reconsider your name empty (as Martijn pointed out) because that thing isn't empty (at least in the end), so the name is misleading.
The classic answer to this problem is to use a slice with a negative step to get what you want:
def reverse(c):
return c[::-1]
...but maybe that's not allowed for you?

Categories

Resources