Can't get function to return false? - python

I'm working with this exercise:
Write a function is_member() that takes a value (i.e. a number, string, etc) x and a list of values a, and returns True if x is a member of a, False otherwise. (Note that this is exactly what the in operator does, but for the sake of the exercise you should pretend Python did not have this operator.)
I wrote this function:
def isMember(value, list):
for element in list:
if(element == value):
return True
else:
return False
myList = ["a","b","c",1,2,3]
print(isMember("a",myList)) #Returns True; correct
print(isMember(3,myList)) #Returns False; why the heck?

You need to take the return False out of the loop:
def isMember(value, list):
for element in list:
if(element == value):
return True
return False
The way you have it currently, isMember will return False if the value is not the first item in the list. Also, you should change the name of your list variable to something other than list, which is a built-in function in Python.

The problem is that your return False is within the loop, directly as the else case of your membership test. So as you loop through the list, you get to the first element and check if it is in the list or not. If it is in the list, you return true—that’s fine. If it’s not in the list, you return false, aborting the loop process and ending the function. So you never look at the other values inside the loop.
So to fix this, move the return False outside of the loop, at the end of the function. That way, only when all elements have been looked at, you return false.
def isMember (value, list):
for element in list:
if element == value:
return True
return False
Another way would be to simplify this using the any function to perform the check for every element in the list. any takes an iterable and looks at the values. As soon as it finds a true value, it returns true. Otherwise it keeps iterating until it finds a false value or hits the end of the iterator, both cases yielding a false. So you could rewrite it like this:
def isMember (value, list):
return any(value == element for element in list)

Related

I can't figure out what is wrong with this function?

This is what it should return
Returns True if all items are truthy.
Examples:
>>> all_true([1, True, 'oregonstate'])
True
>>> all_true([0, 1, 2])
False
"""
This is what I have written
def all_true(items):
for i in items:
if i == True:
return True
else:
return False
pass
Not sure why it is not working, can someone help?
Your function just returns the truthiness of the first item in the list, since it always returns on the first iteration.
You want to do something like this:
def all_true(items):
for i in items:
if not i:
return False
return True
Note that this all_true function already exists in Python. It is the the built-in all function.
Two problems. First, you are returning on the first True thing. In fact, you are returning either True or False on the first thing, regardless. Since you return on both the if and its else clauses, the loop will always return on the first iteration. A bit more subtle, but if there aren't any values in the list, it will return None.
Second, if you want "truthy", don't compare specifically to True. foo == True is False. Instead, just let the if do the boolean test
def all_true(items):
for i in items:
if not i:
return False
return True
all and any are builtin functions that do the same thing. It would generally be preferable to use them.
"All items are truthy" is logically equivalent to "no items are falsy."
def all_true(items):
for i in items:
if not i:
return False
return True
Because 0 is falsy. Also there's no need to implement your own function for that, use Python's built–in all() function instead!

Return in the function is working incorrect

Hey Stackoverflow community,
I am a python newbie.
So, I am trying to build the function any() from scratch. However the output I get is not what I expected. My code is working fine without the second if statement:
def anys(lst):
for i in range(0,len(lst)):
if bool(lst[i])==True:
return True
anys([False,True,False]) executes True as expected.
However, when I am adding a second if statement I get a different outcome:
def anys(lst):
for i in range(0,len(lst)):
if bool(lst[i])==True:
return True
if bool(lst[i])==False or len(lst)==0:
return False
anys([False,True,False]) executes False.
Can anyone help me what I am doing wrong? Any help would be greatly appreciated.
When you are using a return statement, the function will stop executing and, as instructed, return to the place where the function was called from. This means that the function will return at the first elemt in the list since it was False. If you want the function to return false if all of the elemts are false, I would recomend that you put the return False statement after the for loop.
To clearify, the loop starts with the first elemnt in the list, which in this case is False. The element satisfies the condition:
if bool(lst[i])==False or len(lst)==0:
And the function will then return False.
To answer the comment, if you loop through the entire list, and none of the elements are true (in other words "any"), you then want to return false instead.
def anys(lst):
for i in range(0,len(lst)):
if bool(lst[i])==True:
return True
return False
The code now goes through the list, if it ever encounters a True value, it returns True, however if none of the elements are True, it instead returns False.
The basic answer is that with both conditional return statements, you were always returning on the first iteration and ignoring the rest of the values from the list (or other iterable).
But aside from that, a few other hints that could be useful:
You do not need to loop by index number - just loop over the elements in the list directly.
To test whether an expression (here x) would be True if converted into a boolean, all you need to do is if x:
In the correct form with a single conditional return in the loop, it was returning None if no true values were found and the end of the function was reached. But the builtin any returns False in that situation, so an explicit return False is needed if you want to emulate this behaviour.
def anys(lst):
for x in lst:
if x:
return True
return False
Let us execute your second any() function line by line.
First element of input argument is False.
When you check first if condition, if bool(False) == True, it fails.
It reaches to your second if condition.
if bool(False) == False or len(lst) == 0, bool(False) == False is true hence this if condition is executed and your method returns False.

Loop through int array, return True if following int is equal to current

Given a list of ints, return True if the array contains a 3 next to a 3 somewhere.
has_33([1, 3, 3]) → True
has_33([1, 3, 1, 3]) → False
has_33([3, 1, 3]) → False
First Approch:
def has_33(nums):
for i in range(0,len(nums)):
return nums[i] == nums[i+1] ==3
Could someone explain me what's wrong with this approach, I see that this code is returning True only if all the elements in a list are true.
Second Approach:
def has_33(nums):
for i in range(0,len(nums)):
if(nums[i] == nums[i+1] ==3):
return True
The second approach satisfies my question.
What is the difference between these two approaches?
Well, the difference is rather obvious. In the first case, you inconditionnaly return the result of expression nums[i] == nums[i+1] ==3, whatever the value of this expression is. This actually means that you always return on the very first iteration, so your code could as well be written as
def has_33(nums):
if len(nums):
return nums[0] == nums[1] ==3
In the second case, you only return if the expression is true, so the iteration goes on until either you explicitely return (found a match) or the iteration naturally terminates and you've found nothing (in which case the function will implicitely return None).
Unrelated, but your code (second version) can be improved in quite a few ways. First point: Python "for" loop are of the "foreach" kind - you iterate on the sequence elements, not indices. If you don't need the indice, the proper way is
for item in iterable:
do_something_with(item)
no need for range(len(xxx)) and indexed access here.
If you do need both the item and the index, then enumerate() is your friend - it yields (index, item) tuples:
for index, item in enumerate(sequence):
print("item at {} is {}".format(index, item))
Now for your current need - geting (item, nextitem) pairs -, there's still another solution: zip(seq1, seq2) + slicing:
for item, nextitem in zip(sequence, sequence[1:]):
print("item: {} - nextitem : {}".format(item, nextitem))
and finally, if what you want is to check if at least one item in a sequence satisfies a condition, you can use any() with a predicate:
def has_33(nums):
return any((item == nextitem == 3) for item, nextitem in zip(nums, nums[1:]))
Another solution could be to turn nums into a string and look for the literal string "33" in it:
def has_33(nums):
return "33" in "".join(str(x) for x in nums)
but I'm not sure this will be more efficient (you can use timeit to find out by yourself).
In your first approach, you will return the value of
return nums[i] == nums[i+1] == 3 #Where i = 0 since it returns
first iteration.
return nums[0]==nums[1] == 3 #If nums = [0,3,3]
return false # would be your result. But it would never check the next pair of values.
In your second approach, you will return the value
return true #If the if-statement is satisfied
The return function, will end the function call when called. Therefore, if being called in a for-loop without an if-statement, it will be called for the first iteration. If there is an if-statement and the iteration passes through the if-statement, it will return and end the loop at that iteration. Basically, the return function ends the function call and returns the value given.

How to call one of multiple returns?

def sudoku_solver(sudoku):
l = [0, 0]
if not find_empty_location(sudoku, l):
return True
row = l[0]
col = l[1]
for num in range(1, 10):
if check_location_is_safe(sudoku, row, col, num):
sudoku[row][col] = num
if sudoku_solver(sudoku):
return True,sudoku
sudoku[row][col] = 0
return False
def P():
a = np.zeros((9,9))
if sudoku_solver(sudoku):
a = sudoku_solver(sudoku)[1]
else:
a = 1
return a
There are two returns, True and sudoku. How can I call sudoku only in function P? When I run the function P(), it will show
'bool' object is not subscriptable.
You could make your function return a single value that would be either None or the sudoku data.
Python treats None as false so your condition could then be:
...
if sudoku_solver(sudoku):
a = sudoku_solver(sudoku)
...
Note that if sudoku_solver() is a complex and time consuming function, you will want to place its result in a variable BEFORE testing the condition so that it is not executed twice (as would be the case in the above condition)
...
a = sudoku_solver(sudoku)
if a:
...
Another option would be to systematically return a tuple with the boolean and the sudoku data (or None).
Your return statements would have to be changed to return True,sudoku and return False,None
Then your condition could use indexing directly:
...
if sudoku_solver(sudoku)[0]:
a = sudoku_solver(sudoku)[1]
...
but again, you probably don't want to execute the function twice so :
...
ok,a = sudoku_solver(sudoku)
if ok :
...
Another thing is that, if you're passing sudoku as a parameter, you have to realize that your function will modify the content of the calling variable even when it returns False. That may not be what you want but if it is, then there is no point in returning a second value because the caller's instance of the sudoku variable will already be modified and available.
When you see
return True,sudoku
you can catch the returned values like so
result, sudoku = my_function()
or if you've no interest in result
_, sudoku = my_function()
---Edit---
It seems your question centers around the two returns. Namely
return True,sudoku
versus
return False
That's adds unnecessary complexity. Can I suggest you simplify by instead using
return sudoku
and then later
return None
That means you can check the returned value like so
sudoku = my_function()
if (sudoku):
// Do something here
else:
// Do something else
You can't return multiple objects from a function, but you can return a container object, such as a list or tuple, that contains multiple member objects. Try using
return [ True, sudoku ]

recursive search boolean return function

Write a recursive function search(l,key) that returns a boolean: True if key is in the list l; False if it isn’t. Describe the base case(s) and how the smaller problem relates to the bigger one. You may not use the in operator or the index() list method.
Can anyone explain what i need to do here for the description? I dont know anything about recurrsion to know where to start. Its for a exam review lab assignment.
Here is the code i have been provided.
def search(l,key):
"""
locates key in list l. if present, returns True; else returns False.
PRE: l is a list.
POST: l is unchanged; returns True if key in l; False otherwise.
"""
Sample Main:
l1 = [1, '2', 'x', 5, -2]
print search(l1, 'x') # should output: "True"
print search(l1, 2) # should output: "False"
All recursion tends to follow the same rules:
Have one or more terminating cases.
Every other case is a slightly simpler form of the current case.
So, for example, a (very inefficient) way to add two positive numbers a and b:
if b is zero, return a.
otherwise add the two numbers a+1 and b-1.
Something like:
def addtwo (a, b):
if b == 0:
return a
return addtwo (a+1, b-1)
Now let's think about the cases for your assignment:
if the list is empty, you didn't find it: return false.
if the first element of the list is equal to your key, you found it: return true.
otherwise look in the list made by removing the first element.
In pseudo-code (which is very similar to Python but different enough that you'll have to do some work):
def search (list, key):
if list is empty:
return false
if key == first item in list:
return true
return search (list with first element removed, key)
Every question regarding recursion should be dealt with the same way (usually)...Ask yourself what is the base case and then build on that for higher cases...
So in this question, ask yourself, when can i be certain there is no key in the list...
It's obviously when the list is empty, you're certain it's not present.
For a bigger list, you compare the first element, if it's the same as the key, you return True right away, but incase it's not, you perform all the checks for the rest of the list....
So studying all these aspects,
Here's your Algorithm.
function locate(lst,key)
if lst == emptylist then return False
if lst[0] == key then return True
else return locate(lst[1..],key) //i use the notation lst[1...] to indicate list starting from 1 index.

Categories