python if/else logic explained please - python

I have a really basic if/else logic question for Python. An exercise in the book required me to write a function that takes a list of integers are returns True if the list contains all even numbers and False if it doesn't.
I wrote:
list1 = [8,0,-2,4,-6,10]
list2 = [8,0,-1,4,-6,10]
def allEven(list):
for x in list:
if x % 2 != 0:
return False
else:
return True
This code always returns True. Why is that? Doesn't the code see the -1 during the loop of all the values of the list and returns the False?
list1 = [8,0,-2,4,-6,10]
list2 = [8,0,-1,4,-6,10]
def allEven(list):
for x in list:
if x % 2 != 0:
return False
return True
The book gives the answer of this. Why does this work and mine doesn't?

Pay close attention to where that else is placed. Indentation and nesting matters here!
In your first example, it will return True on the first element that satisfies your condition because your first if check fails.
In your second example, it will return True after all elements have been iterated through and a return value hasn't been produced.

The first function checks the first number only, since it returns something as soon as the for loop starts.
By the way, you can but should not use list as an argument or a variable name, since it is a keyword.

I strongly recommend writing a print statement to output x before both of your return statements. It will help you understand the flow of the code.
The short answer is that only the first element is being checked by your code, and the function returns True or False based on that value.
In the book solution, any failure causes a return of False, but the loop simply continues otherwise. Only if all elements are checked without failure does the return True reached.

Related

wondering why my list has bigger number than second argument function return False?

def greater(list, num)
for x in list:
if x > num:
return True
else:
return False
as you can see in my code, i am trying to write a function that return True if list_number contained number that is bigger than second argument, otherwise return False.
but here is confusing:
when i input: greater([1, 2, 3], 2), and its return False. I am wondering why is that? the first argument contained 3 and its bigger than 2.
any helps and explanations will be appreciated.
You want to have it return at the end of the function. Right now, you have it return after checking only the first number. Try this:
def has_gt(list_number,number):
for x in list_number:
if x > number:
return True
return False
A property of if/else is that if one runs, the other doesn't. But in both cases, one runs. In your code, this snippet:
if x > number:
return True
else:
return False
Means that it will check if the number is bigger than the number in question. If it is, it will return True. If not, it will return False. A return call instantly ends the processing of a function, so it will stop checking after that.
To summarize, your code loops through the target list. It checks the first number, one, and sees if it is bigger than two. It is not, so the code returns False, instantly ending the function. So, your function just ended in a False, which is what it returned.
The change I made was that it returns False at the end of the code. This means that it will check each value for being greater than the target. If it finds any value greater than the target, it will end processing, with a return value of True. If the code hasn't returned by the time it reaches the end of the function, it will return False because of the statement at the end of the function.
Actually what happens is the else part also runs just after comparing the number (here 2) with the first element in the list_number (here 1) thus returns false.
So the solution is you need to let the for loop first run completely which is stopped by the else statement.
def has_gt(list_number,number):
for x in list_number:
if x > number:
return True
return False

How to find if there are 2 elements of same value consecutively in a list?

For example,
[1,3,3,5] should return True while [1,3,1,3] should return False.
I am looking for a simple solution using loops.
I tried the following:
def conseq(nums):
for i in range (len(nums)):
if nums[i]==nums[i+1]:
return True
break
else:
return False
The first time your function encounters 2 consecutive numbers which are different, it returns False. Returning from a function ends that function immediately, the function does not continue after that. This is also why the break is not necessary.
Another issue with your code is that once you reach the final number, nums[i + 1] will access out of the bounds of the array. That's why you should iterate over len(nums) - 1 rather than len(nums) - there's no reason to check the final number because there's nothing after it.
def conseq(nums):
for i in range(len(nums) - 1):
if nums[i]==nums[i+1]:
return True
# Only return False once we've exhausted all numbers.
# Since we didn't return True so far - it means there are
# no consecutive equal numbers, so we can safely return False
return False
the return ends the function, so here it will stop the processing as well
your true statement mostly works, and the break is unnecessary
you don't want the else statement until after the for loop ends (it returns False only if everything else has been parsed)
Also the way you parse through the code, nums can't access nums[i+1] when you're at the final nums so you need the range len(nums) - 1
If you feel like putting an else that does nothing, you can with a single semicolon or pass I believe, but the else is unnecessary here
def conseq(nums):
for i in range (len(nums)-1):
if nums[i]==nums[i+1]:
return True
else:
;
return False
You can't return False until the loop is done (since the match may be in the part of the list you haven't checked yet). And the break after return will never happen (since return ends the function and everything in it).
Enumerate list without last (to avoid try catch for i+1 being out of range) then compare each item with next one and return True if they are same. After loop return False because none are similar consequtively (returns break functions)
def function(number_list):
for i, item in enumerate(number_list[:-1]):
if item == number_list[i+1]:
return True
return False
def conseq(nums):
for i in range (len(nums)):
if nums[i]==nums[i-1]:
return True
return False
I modified your Code. Please check and let know if useful
def conseq(nums):
flag=True
for i in range (len(nums)-1):
if nums[i]==nums[i+1]:
print(True)
flag=False
break
else:
continue
if(flag):
print(False)
nums=[1,3,3,5]
nums1=[1,3,1,3]
conseq(nums)
conseq(nums1)
We have many solutions here already. I have tried out using numpy without a loop:
>>> import numpy as np
>>> f = np.array([1,3,3,5])
>>> (np.where(np.diff(f) == 0)[0]).astype('bool')[0] #check if we have any difference of two elements 0?
True

I get an error when I end the if statement with a concluding else statement

I wrote this Python code that would check a list and return True if two items in the list next to each other are of the same value:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
else:
return False
Result 1:
>>> samer([1,3,44,5,5,8])
False
This is where I'm puzzled because I feel it should return True.
Result 2:
>>> samer([3,3,49,93,5,8])
True
It only returns True if the first and second number in the list is True.
The solution:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
return False
The above code works well, so my question is since the else statement indented under the if condition's purpose is to return False if no number in the list is next to each other in the process of the for loop, why do I still get False in Result 1?
Is it that it doesn't loop again after checking the first two boxes and why is that since it's the purpose of the for loop to go over each iteration and then check for the conditions?
When a function returns, that's it. The function is done, over, finished..
Since you're returning either true or false when checking each and every element, you really only check the first time through the loop (elements one and two), as you observe.
You should return true if a match is found and only return false at the end, when you've checked everything and, therefore, no matches are found. That code is already in your question, the bit under The solution.
So to chip in here, once that first iteration check occurs, we know that it's going to be returning False as the first two elements are not the same and the program ends there. If you want to really see that this is the case, make use of print() built-in function to see what's going on everytime the element is iterated within the for loop:
Like this:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
print(True)
else:
print(False)
### adding a main method is always a good idea for clarity.
if __name__ == "__main__":
print(samer([1,3,44,5,5,8]))
Output is this:
False
False
False
True
False
See it returned True for the 3th element as they are equal and next to each other.
But with the way you had it structured in the first example it does return False as it hit the roadblock once it checked and saw that the first iteration were not equal to each other and thus returned False.
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
else:
return False
if __name__ == "__main__":
print(samer([1,3,44,5,5,8]))
Output is:
False
With your solution approach which is great, the loop only 'terminates' when it really cannot find a match (same two numbers), it will return False without depending on a else statement. So if it finds a match then it will return True which is does and then stops iterating and exits the program.

Python any() function does not act as expected for list of negative numbers

I am trying to compare a list of numbers in an if statement with the any() function. I am using python 3.6 in Spyder. The code in question is:
if any(lst) >= 1:
do_some_stuff
lst is actually generated by list(map(my_func, other_lst)) but after diagnosing my problem I get two behaviors as shown below with my actual lst passed to the any() function:
any([1.535, 1.535, 1.535]) >= 1
>>True
Which is expected.
any([-0.676, -0.676, -0.676]) >= 1
>>True
Which is not expected.
I've delved deeper and found that any number I can put in lst that is less than 0 yields True in my if statement. Also, converting the 1 to a float doesn't help. After reading "truth value testing", this post, and extensive time trying to learn the behavior within my program, I am at a loss. Please help, I am pretty new to python. Thanks!
You are comparing the wrong thing. You are comparing the result of any to 1.
any(mylist) will return true if any element of the list is nonzero. True is greater than or equal to 1.
So this
any(mylist)>=1
is equivalent to just
any(mylist)
What you mean is
any(x>=1 for x in mylist)
Please read the documentation:
any(iterable)
Return True if any element of the iterable is true. If
the iterable is empty, return False. Equivalent to:
def any(iterable):
for element in iterable:
if element:
return True
return False
All your any() expression listed will return True, and you are comparing True with 1, that is True.

Function that checks if a string occurs in another string

I'm currently reading and doing each and every of the exercises in John Guttag's Introduction to Computation and Programming Using Python. One particular problem I cannot solve for the life of me:
Write a function isIn that accepts two strings as arguments and
returns True if either string occurs anywhere in the other, and False
otherwise. Hint: you might want to use the built-in str operation in.
I went through every discussion I could find here, tried with both in and find, constantly changing something in the code, but every time I would run my program to check if 'abc' occurs in 'efg' the answer would be True.
Any idea how to solve it? Again, I need to write a function, not simply go with in like:
x='abc'
y='efg'
if x in y:
# Blah
else:
# another Blah
The code I wrote (I'm adding this as apparently some would like to see it) was basically this:
def isIn(x,y):
if x in y or y in x:
return True
else:
return False
a='abc'
b='efg'
isIn(a,b)
if True:
print "True"
else:
print "False"
The problem is that you are completely ignoring the return value of the function isIn, and the reason why you always get True printed by the code is that the condition you are checking in the if statement is the boolean constant True, which is of course always True.
Try changing your code to:
a='abc'
b='efg'
r = isIn(a,b)
if r:
print "True"
else:
print "False"
Simply put:
x=input('Enter string #1: ')
y=input('Enter string #2: ')
#can also just define x and y separately in the console and invoke the
# function on those values
def isIn(x,y):
if x in y:
return True
elif y in x:
return True
else:
return 'False'
print(isIn(x,y)) #invokes and prints the results of the function evaluating
#the x and y the user inputs; otherwise nothing is returned
I'm getting the impression that you are a newcomer to Python, so here is the solution to your problem below laid out just as the question asks :)
def isIn(string_1, string_2): #This is the function that returns true/false
if (string_1 in string_2) or (string_2 in string_1):
is_in = True
else:
is_in = False
return is_in
if __name__ == "__main__":
string_1 = input ("String 1 here: ")
string_2 = input ("string 2 here: ")
is_in = isIn(string_1, string_2) #Calls function with strings as parameters
print (is_in) #Prints the evaluation of the function after it has run
The problem with your code was that you say if True, but you aren't giving it anything to check against. if True on its own is always true.
If you want me to explain how this code works in more detail I'd be happy to do so :)
you are not printing the isIn(x,y)
def is_in(x,y):
if x in y or y in x:
return True
else:
return False
print(is_in("hello","hello world"))
try this :)

Categories

Resources