Python recursion, how come my function doesn't work? - python

I am trying to write a Python 3 recursive function which will tell me if an integer is in a nested list. I am not sure how I can make my code return True if it finds it in the list, and False if it doesn't find it in the list. When I print the result of my for loop, I get a bunch of
false
false
false
false
true
false
false
false
etc. But, it returns False because the last call was false, even though I want it to return true. How can I fix this?
Here is my code:
def nestedListContains(NL, target):
if( isinstance(NL, int) ):
return NL
for i in range(0, len(NL)):
return ( nestedListContains(NL[i], target) == target )
return False
And here is how I'm calling it
print(nestedListContains([[3], [4,5,7], [[[8]]]], 8))
EDIT: This seems to be working for me, but it seems rather ghetto:
def nestedListContains(NL, target):
if( isinstance(NL, int) ):
if( NL == target ):
return 1
return 0
x = 0
for n in NL:
x += nestedListContains(n, target) == 1
return x != 0

My attempt:
def contains(lst, target):
if isinstance(lst, int):
return lst == target
return any(contains(x, target) for x in lst)

You return the result regardless of whether it's True or not. You could do something like this:
def nestedListContains(NL, target):
if isinstance(NL, int):
return NL == target
for n in NL:
result = nestedListContains(n, target)
if result:
return result
return False

Using duck typing for #gatto's solution
def contains(lst, target):
try:
return any(contains(x, target) for x in lst)
except TypeError:
return lst == target

Related

Why does my code output 'true' when ran on LeetCode but 'false' when ran on my own? (python3)

Not sure what to do here, anyone know what's up? I'm trying to find if a number is a palindrome, and I'm getting hung up with the input -121. The output should be 'false', as in it is not a palindrome, whereas 121 is.
LeetCode code:
class Solution:
def isPalindrome(self, x: int) -> bool:
x = str(x)
xrev = x[::-1]
if x == xrev:
return 'true'
else:
return 'false'
This returns 'true', 'false' is expected. Whereas my code ran on Atom returns 'false' as expected:
def isPalindrome(x):
x = str(x)
xrev = x[::-1]
if x == xrev:
return 'true'
else:
return 'false'
print(isPalindrome(-121))
As #khelwood in the comments pointed out, since the LeetCode code is hinted to return a boolean, the string value is automatically converted to a boolean value, which only if the string is empty, will return False.
Corrected code:
class Solution:
def isPalindrome(self, x: int) -> bool:
x = str(x)
xrev = x[::-1]
if x == xrev:
return True
else:
return False
try this, instead of true and false return 1 and 0:
class Solution:
def isPalindrome(self, x) -> bool:
x = str(x)
xrev = x[::-1]
if x == xrev:
return 1
else:
return 0

Python - Update a function/return assigned to a var

Code first so you'll understand what I'm talking about :
goal = False
count = 0
def function():
if goal==True:
return True
else:
return False
def func():
if dict1["A"]==True:
return True
else:
return False
dict1 = {"A":function()}
dict2 = {"B":func()}
list = [dict1,dict2]
goal = True
for i in list:
count = 0
for x,y in i.items():
if y==True:
count+=1
if count==len(i):
print("Works")
else:
print(i)
>>>{"A":False}
>>>{"B":False}
This is not my current code, but it is the actual issue. This is where I'm asking, how can I update the values in the dicts. Should I do something like :
for i in list:
for x,y in i.items():
y()
?
My current project is used in Ren'Py (.rpy) but as I'm using python blocks, the code works exactly as normal Python.
Within a class named Event, my elements are exactly as it follows:
def ev_check(self):
if self.done==False:
self.count = 0
for x,y in self.conditions.items():
if y==True:
self.count+=1
else:
pass
if self.count==len(self.conditions):
self.valid = True
else:
self.valid = False
else:
self.valid = False
def own_office():
if Promotion_1.done==True: #Once the event is played, .done gets True
return True
else:
return False
def times_worked(x):
if You.worked < x:
return False
else:
return True
Promotion_1.conditions = {"Work 2 times" : times_worked(2)}
Meet_Tigerr.conditions = {"Own office" : own_office()}
#External event that adds a value to the data named You.worked to get it to 2
print(Promotion_1.conditions["Work 2 times"])
>>> False
Expected result : True
Result : False
You can create your custom dict and have this feature. You may try something like this:
class MyDict(dict):
def __getitem__(self, item):
val = super().__getitem__(item)
if callable(val):
return val()
return val
It will work exactly like a dict, except that it will call the callable values for you every time.
d = MyDict()
d['m'] = 1
d['m']
Out[28]: 1
task
Out[33]: <function __main__.task()>
task()
Out[34]: True
d['t'] = task
d['t']
Out[36]: True
EDITED : Modified the code a bit to show how you can even have argument values passed for your parameterized functions:
def func():
return True
def param_func(i):
return 2*i
def param_func2(i, j):
return i*j
class MyDict(dict):
def __getitem__(self, key):
if isinstance(key, tuple):
super_key = key[0]
else:
super_key = key
super_val = super().__getitem__(super_key)
if callable(super_val):
if isinstance(key, tuple):
args = key[1:]
return super_val.__call__(*args)
else:
return super_val.__call__()
return super_val
if __name__ == "__main__":
d = MyDict()
d['num'] = 1
print(d['num'])
d['func'] = func
print(d['func'])
d['param_func'] = param_func
print(d['param_func', 2])
d['param_func2'] = param_func2
print(d['param_func2', 2, 6])
Output :
1
True
4
12

Can I create a master function in Python to take a single line of other functions?

I have two functions that contain mostly the same code. One returns "True" if the array passed in contains all positive numbers while the other returns "True" if the array contains all numbers that are divisible by 10.
I want to combine these two functions into a function like this:
def master_function(array, function):
for i in array:
if function:
result = True
else:
result = False
break
print(result)
return result
The only part that would vary is the "function" in the If statement. When I write functions with the missing line they don't get called as the program executes.
def positive_integers(array):
i >= 0
def divisible_by_10(array):
i%10 == 0
The test code isn't executed either.
master_function([10,20,30,35],divisible_by_10)
Your functions aren't returning anything, and you need to give them access to i:
def positive_integers(i):
return i >= 0
def divisible_by_10(i):
return not i%10
def master_function(array, function):
for i in array:
if function(i):
result = True
else:
result = False
break
print(result)
return result
Your function don't return anything. Also, you need read about all and any:
def positive_integers(array):
return all(i >= 0 for i in array)
def divisible_by_10(array):
return all(i % 10 == 0 for i in array)
def master_function(array, function):
return function(array)
def master_function(array, function):
for i in array:
print str(i)
if function(i):
result = True
else:
result = False
print(result)
return result
def positive_integers(i):
if i >= 0:
return True
def divisible_by_10(i):
if i%10 == 0:
return True
master_function([10,20,30,35],divisible_by_10)

Tracking on/off state in a sequence

I have a generator function that tracks whether I am between a certain pair of events-- a "start" event and an "end" event. For example, it could be examining tokens and reporting whether I am between the comment delimiters "/*" and "*/" (non-nesting). The following code works, but is there a nice itertools combination or logical restructuring that would simplify it (and/or make it more "pythonic")?
def tokspan(starttok, endtok, stream):
inside = False
for tok in stream:
if (not inside) and tok == starttok:
inside = True
yield (inside, tok)
if inside and tok == endtok:
inside = False
tstream = "int x; /* a non-nesting comment /* etc. */ x=1; main();".split()
for status, tok in tokspan("/*", "*/", tstream):
print(status, tok)
The above (intentionally) returns True for the boundary tokens (/* and */), but that's not particularly important. If you have an approach that happens to exclude one or both boundaries (like python ranges do), I'd still like to know about it.
The only simplification that I can think of is rewriting the logic around setting/resetting inside:
def tokspan(starttok, endtok, stream):
inside = False
for tok in stream:
inside |= (tok == starttok)
yield (inside, tok)
inside &= (tok != endtok)
Whether this makes the code more or less readable is in the eye of the beholder.
It might be possible to use a decorator over here. I am not sure if this is going to be useful to you or not but this might just give you some ideas.
Create a decorator which stores the items you want to filter out with:
import itertools as it
class insideDec(object):
def __init__(self, start, stop):
self.start = start
self.stop = stop
def __call__(self, f):
def wrapper(x):
x1 = it.dropwhile(lambda m: not m.startswith(self.start), x )
x1.next()
x2 = it.takewhile(lambda m: not m.startswith(self.stop), x1 )
return f(x2)
return wrapper
#insideDec('{', '}')
def f(val):
return val
if __name__ == '__main__':
print ''.join(f('This is some {string that needs to} be printed'))
Now you apply the decorator to a function that accepts a string. This will convert the function into one whose input is an iterator. You then process the iterator like you would any other iterator.
Of course, you can always convert the iterator to a string at any point of time (like for example over here):
# rest of the code ...
x2 = it.takewhile(lambda m: not m.startswith(self.stop), x1 )
return f(''.join(x2))
# rest of the code ...
That's really up to you ...
Edit:
Sorry about that. I misread your question. For tokenizing, maybe something like the following might help?
class tokenize():
def __init__(self, strVal, start, stop):
self.start = start
self.stop = stop
self.strTees = it.tee(strVal, len(start))
self.inside = False
for i, strTee in enumerate(self.strTees):
for j in range(i):
next(strTee, '')
self.strVals = it.izip( *self.strTees )
def __iter__(self):
return self
def next(self):
v = ''.join(self.strVals.next())
if v == '': raise StopIteration
if v == self.start: self.inside = True
if v == self.stop: self.inside = False
# print '[',v, ']'
return (v[0], self.inside)
if __name__ == '__main__':
strVal = 'int x; /* a non-nesting comment etc. */ x=1; main();'
for x, y in tokenize( strVal, '/*', '*/' ):
print x, y
Again, this is not perfect, by might serve your purposes ...
Here is the output:
i False
n False
t False
False
x False
; False
False
/ True
* True
True
a True
True
n True
o True
n True
- True
n True
e True
s True
t True
i True
n True
g True
True
c True
o True
m True
m True
e True
n True
t True
True
e True
t True
c True
. True
True
* False
/ False
False
x False
= False
1 False
; False
False
m False
a False
i False
n False
( False
) False

(Beginner)Python functions Codeacademy

I'm just learning to program on Codeacademy. I have an assignment, but cant figure out what I'm doing wrong.
First I need to define a function that returns the cube of a value. Then I should define a second function that checks if a number is divisible by 3. If it is I need to return it, otherwise I need to return False.
heres the code:
def cube(c):
return c**3
def by_three(b):
if b % 3 == 0:
cube(b)
return b
else:
return False
You are not catching the return value of the function cube. Do b = cube(b). Or better yet, do return cube(b).
def cube(c):
return c**3
def by_three(b):
if b % 3 == 0:
b = cube(b)
return b # Or simply return cube(b) and remove `b = cube(b)`
else:
return False
When you call the cube function with the argument b, it returns the cube of the passed argument, you need to store it in a variable and return that to the user, in your current code, you are neglecting the returned value.
I think this answer might also work:
def cube(b,c):
b = c ** 3
if b % 3 == 0:
return b
else:
return False
return b
I know that might be a little redundant but I think that might be another way of doing what you're trying to do. What Sukrit did I think is simpler.
I have finished Codecdemy and this is my code.
def cube(n):
return n ** 3
def by_three(number):
if number % 3 == 0:
return cube(number)
else:
return False
Here's a lightweight solution I just developed, should work :)
def cube(number):
return number**3
def by_three(number):
if number % 3 == 0:
return cube(number)
else:
return False
def cube(num):
return n ** 3
def by_three(value):
if value % 3 == 0:
return cube(value)
else:
return False
try calling the same letter for each. Instead of using 'c' and 'b', just use 'c'
def cube(c):
return c**3
def by_three(c):
if c % 3 ==0:
return cube(c)
else:
return False

Categories

Resources