def func_palindrome(stri):
if len(stri) == 0 or 1:
return True
if stri[0] != stri[-1]:
return False
return func_palindrome(stri[1:-1])
I'm not sure if this function, that checks if the string is a palindrome can be considered as a recursive code or not. That becuase I can simply change the last return value from return func_palindrome(str[1:-1]) to True and nothing will change
Your issue is here:
if len(str) == 0 or 1 :
should be
if len(str) == 0 or len(str) == 1:
By just doing if len(str) == 0 or 1 it is evaluating to True always as it is interpreted as (len(str) == 0) or 1
Also, I would rename str to something else, as str is a builtin type
Any function that calls itself is technically a recursive function.
Any function that checks its arguments for a "base case", and otherwise calls itself with a "smaller" version of its arguments, is a usefully recursive function.
Of course a recursive function can still be broken, or even pointless. For example, consider this function:
def recursive_length(a):
if not a:
return 0
return 0 + recursive_length(a[1:])
My stupid bug in the last line doesn't mean this is not a recursive function. I'm recursively summing up N copies of the number 0, instead of N copies of the number 1, so I could have done the same thing by just writing return 0. But that's just because the sum of N copies of 0 is always 0, not because my function fails to be recursive.
So, what if there were a problem in the base case?
def recursive_length(a):
if a is not None:
return 0
return 1 + recursive_length(a[1:])
Now, it never actually recurses… but it's still a recursive function. It's just a recursive function with a bug in the base case.
You don't need to do this recursively, but you can, particularly if you don't mind a lot of extra space and poor performance for long strings.
Here are two nonrecursive ways:
#!/usr/bin/python3
def is_palindrome1(string1):
string2_list = list(string1)
string2_list.reverse()
string2 = ''.join(string2_list)
return string1 == string2
def is_palindrome2(string):
len_string = len(string)
for index in range(len_string // 2):
character1 = string[index:index+1]
character2 = string[len_string-index-1:len_string-index]
if character1 == character2:
# This character is good
pass
else:
return False
# all characters matched
return True
for string in [ '393', '339', 'aibohphobia', 'aibobphobia' ]:
assert is_palindrome1(string) == is_palindrome2(string)
print(is_palindrome1(string))
print(is_palindrome2(string))
Related
why does the output of these two functions give different outputs when the logic or idea is the same and they are working with the same string?
def solution(inputString):
a = ""
b = a[::-1]
if a == b:
return True
else:
return False
print(solution("az"))
def ans(something):
if something == reversed(something):
print(True)
else:
print(False)
ans('az')
This is I think because you are not using your inputString parameter in the function solution(). This may be closer to what you want:
def solution(inputString):
a = inputString
b = a[::-1]
if a == b:
return True
else:
return False
when the logic or idea is the same
No, the solution and ans functions have different logic.
solution uses the common way of reversing a string, thats fine
However, the second function uses reversed() function, which does:
reversed(seq)
Return a reverse iterator. seq must be an object which has a __reversed__() method or supports the sequence protocol ...
It does not return the reversed string as you'd probably expected.
To put that in perspective, the following code returns False:
print("oof" == reversed("foo"))
Because the return value of reversed("foo") is an <reversed object> and not the reversed String.
I am new to Python 3 and currently practicing with functions. I wanted to first write a function that returns True or False depending on whether its parameter (int) is even.
def isEven(number):
if number % 2 == 0:
return True
elif number % 2 != 0:
return False
This worked as I could print the return value with the print() function.
However, I had problems when I wanted to write a second function, which is the isOdd() function. I wanted it to negate the whatever return value of isEven(). I tried:
def isOdd (number):
return not isEven(number)
Is there a more efficient way, say, by creating a conditional statement in isOdd()?
Then you might not need isOdd(), since isEven() will return false then.
You can also eliminate the if-elif statement:
def isEven(number):
return number%2 == 0
If we talk about only this example then you can use if. But if isEven is bigger in realtime world, you should call it in isOdd
I'd minimize isEven with like this
def isEven(number):
return number % 2 == 0
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Right now I'm trying to use recursion of a function with two parameters to find whether or not the second is included in the first. As an example:
def recurseString(full, inclusive):
...............
With this I would take something along the lines of:
recurseString('jack','kcj')
and this would return "True" whereas something like:
recurseString('stan','xun')
would return "False"
I'm rather new to python so this is rather confusing. Any ideas on how to go about this problem?
I am guessing that you are looking for ...
In [51]: def recurseString(a,b):
....: if b == '': return True
....: else:
....: if len(b) == 1: return b in a
....: else: return (b[0] in a) and recurseString(a, b[1:])
....:
In [52]: recurseString('jack', 'kjc')
Out[52]: True
In [53]: recurseString('stan', 'xun')
Out[53]: False
However, there is no need for recursion. This is much better solved using all like so:
In [57]: all( [s in 'jack' for s in 'kjc'] )
Out[57]: True
which is far more Pythonic.
It is also possible to use reduce which is more functional but much less readable, since Python has much better ways of handling this.
In [60]: reduce(lambda x,y: (x and (y in 'jack')) , 'kjc', True)
Out[60]: True
Finally, this wouldn't be complete without using the set notation:
In [65]: (set('kjc') - set('jack')) == set()
Out[65]: True
So as you can see, the recursive version is the least suitable for this problem!
This will return True even if there are duplicate letters in inclusive but but only one in full:
def recurseString(full, inclusive):
if not inclusive:
return True
return inclusive[0] in full and recurseString(full, inclusive[1:])
>>> print recurseString('jack','kkkcccjjj')
True
The following requires full to contain the same number of duplicate letters - if inclusive has three k's full must have three k's:
def recurseString(full, inclusive, first_call = True):
# first time through, sort the arguments to make the algorithm easier
if first_call:
full, inclusive = map(sorted, (full, inclusive))
first_call = False
# two base cases, inclusive has been exhausted
if not inclusive:
return True
try:
index = full.index(inclusive[0])
except ValueError:
# and (2nd base case) first item of inclusive is not in full
return False
return recurseString(full[index+1:], inclusive[1:], first_call)
>>> print recurseString('jack','kkkcccjjj')
False
>>> print recurseString('jckackjkjc','kkkcccjjj')
True
>>>
Using the index method seemed like cheating -
def foo(full, inclusive, first_call = True):
if first_call:
full, inclusive = map(sorted, (full, inclusive))
if not full and inclusive:
return False
if not inclusive:
return True
if inclusive[0] == full[0]:
inclusive = inclusive[1:]
return foo(full[1:], inclusive, False)
assert not foo('','kkkcccjjj')
assert not foo('sun','xun')
assert not foo('jack','kkkcccjjj')
assert foo('s', 's')
assert foo('jckackjkjc','kkkcccjjj')
assert foo('','')
assert foo('a','')
To think about any problem recursively, you have to break it into a base case (or sometimes multiple base cases), and a recursive case (or sometimes multiple recursive cases).
I'm going to assume that "included by" means "each character in inclusive is also in full, and in fact each character that appears in inclusive N times is also in full at least N times".
So, if inclusive is empty, it's vacuously True.
But if the full is empty and inclusive is not, it's False.
Otherwise, if the first character of full is in inclusive, it's true iff full[1:] contains inclusive minus that character.
Otherwise, it's true iff full[1:] contains inclusive.
Now you just have to translate that to code.
If you don't need to handle repeated characters, you can simplify this by just testing inclusive[0] and recursing on inclusive[1:], instead of recursing on full[1:].
def recurseString(str1,str2):
if str2 == "": # str2 == "" all str2 letters are in str1
return True
elif str2[0] in str1:
return recurseString(str1, str2[1:]) # move to next letter in str2
return False # if we get here we have found a letter that is not in str1
In [22]: recurseString('stan','xun')
Out[22]: False
In [23]: recurseString('jack','kcj')
Out[23]: True
I don't know why you need recursive to implement it, it's difficult to read and understand.
MY GOD, It's a challenge for me to read my code.
def recurseSring(full, inclusive):
for i in range(len(full)):
for j in range(len(inclusive)):
if full[i] == inclusive[j]:
if recurseSring(full[i + 1:], inclusive[j + 1:]):
return True
if full[i] == inclusive[j] and len(inclusive) == 1:
return True
return False
if __name__ == "__main__":
if recurseSring('lifenglifeng001', 'lifeng'):
print('OK, equal')
else:
print('NOT equal')
Short but sweet.
def recurseString(full, incl):
return incl[:1] in full and (incl[:1] == '' or recurseString(full, incl[1:]))
The 'and' ensures both parts of the expression are true.
The first part - takes the first character of inclusive and searches for it in the full string:
incl[:1] in full #returns '' if incl is ''
The second part - this is true if you search with a null string (incl), have come to the end of incl OR if the recursive call is true called with the tail of incl used as the second arg:
incl[:1] == '' or recurseString(full, incl[1:])
#null check is first to prevent overflow
There's a simple approach for this without recursion: create two sets with the strings you want and check if one set is inside the other one.
def contains(text, chars):
textset = set(text)
charset = set(chars)
return charset.issubset(textset)
print contains("jackie", "ice") # True
print contains('jack','kcj') # True
print contains('stan','xun') # False
I have a function called check defined like so
def check(n):
if n > 17325551999:
return True
return False
which is always returning true. eg
>check(1000000000)
True
>check(5)
True
Can anyone give me some insight as to why this is happening? Is it because the number is larger than the largest possible int?
edit: I've added a picture of my python prompt.
Updated answer:
From your screenshot it is clear you didn't post the same code here as what you are actually running:
def check(num):
if n > 17325551999:
return True
return False
either raises a NameError for 'n' or tests n as a global if it is defined. The actual parameter to the function is called num, and is completely ignored in the function.
In other words, you'd have to assign to the n global to make your version work.
The fix is to test the right parameter:
def check(num):
return num > 17325551999
Previous answer before the screenshot was posted:
You are not passing in integers. With integers your code works just fine:
>>> def check(n):
... if n > 17325551999:
... return True
... return False
...
>>> check(5)
False
Instead you are probably passing in strings instead:
>>> check('5')
True
In Python 2, numbers always sort before strings (a mistake remedied in Python 3), so any number is always going to be 'smaller' than a string:
>>> '0' > 0
True
Avoid this problem by making sure your function is called with an integer argument, or explicitly convert n in the function:
def check(n):
return int(n) > 17325551999:
Note that the > operator already returns True or False, no need to use if here.
I have always thought that using -1 in a condition is alway the same as the writing False (boolean value). But from my code, I get different results:
Using True and False:
def count(sub, s):
count = 0
index = 0
while True:
if string.find(s, sub, index) != False:
count += 1
index = string.find(s, sub, index) + 1
else:
return count
print count('nana', 'banana')
Result: Takes to long for interpreter to respond.
Using 1 and -1:
def count(sub, s):
count = 0
index = 0
while 1:
if string.find(s, sub, index) != -1:
count += 1
index = string.find(s, sub, index) + 1
else:
return count
print count('nana', 'banana')
Result: 1
Why does using -1 and 1 give me the correct result whereas using the bool values True and False do not?
string.find doesn't return a boolean so string.find('banana', 'nana', index) will NEVER return 0 (False) regardless of the value of index.
>>> import string
>>> help(string.find)
Help on function find in module string:
find(s, *args)
find(s, sub [, start [, end]]) -> int
Return the lowest index in s where substring sub is found,
such that sub is contained within s[start,end]. Optional
arguments start and end are interpreted as in slice notation.
Return -1 on failure.
>>>
Your example simply repeats:
index = string.find('banana', 'nana', 0) + 1 # index = 3
index = string.find('banana', 'nana', 3) + 1 # index = 0
The -1 version works because it correctly interprets the return value of string.find!
False is of type bool, which is a sub-type of int, and its value is 0.
In Python, False is similar to using 0, not -1
There's a difference between equality and converting to a boolean value for truth testing, for both historical and flexibility reasons:
>>> True == 1
True
>>> True == -1
False
>>> bool(-1)
True
>>> False == 0
True
>>> bool(0)
False
>>> True == 2
False
>>> bool(2)
True
I have always thought that using -1 in a condition is alway the same as the writing False (boolean value).
1) No. It is never the same, and I can't imagine why you would have ever thought this, let alone always thought it. Unless for some reason you had only ever used if with string.find or something.
2) You shouldn't be using the string module in the first place. Quoting directly from the documentation:
DESCRIPTION
Warning: most of the code you see here isn't normally used nowadays.
Beginning with Python 1.6, many of these functions are implemented as
methods on the standard string object. They used to be implemented by
a built-in module called strop, but strop is now obsolete itself.
So instead of string.find('foobar', 'foo'), we use the .find method of the str class itself (the class that 'foobar' and 'foo' belong to); and since we have objects of that class, we can make bound method calls, thus: 'foobar'.find('foo').
3) The .find method of strings returns a number that tells you where the substring was found, if it was found. If the substring wasn't found, it returns -1. It cannot return 0 in this case, because that would mean "was found at the beginning".
4) False will compare equal to 0. It is worth noting that Python actually implements its bool type as a subclass of int.
5) No matter what language you are using, you should not compare to boolean literals. x == False or equivalent is, quite simply, not the right thing to write. It gains you nothing in terms of clarity, and creates opportunities to make mistakes.
You would never, ever say "If it is true that it is raining, I will need an umbrella" in English, even though that is grammatically correct. There is no point; it is not more polite nor more clear than the obvious "If it is raining, I will need an umbrella".
If you want to use a value as a boolean, then use it as a boolean. If you want to use the result of a comparison (i.e. "is the value equal to -1 or not?"), then perform the comparison.