CodeAcademy's Python course is running me through loop functions and I don't understand an outcome. The goal is to see if a list is a mirror of the other list. i.e. [1,2,3] to [3,2,1]
After 20 minutes I looked at the solution and I don't understand why this does not return True every time?:
def reversed_list(lst1, lst2):
for index in range(len(lst1)):
if lst1[index] != lst2[len(lst2)-1-index]:
return False
return True
The "return True" is indented to the same level as "for index", which would override any value returned from the prior line.
Alternatively, when I introduce an "else" at the "if" indentation, everything returns True:
def reversed_list(lst1, lst2):
for index in range(len(lst1)):
if lst1[index] != lst2[len(lst2)-1-index]:
return False
else:
return True
Can anyone help a noob?
The return False causes the function to exit completely while returning False, so the return True line is never reached in that case. Placing an early return statement is a way of interrupting function execution
If your statement if lst1[index] != lst2[len(lst2)-1-index] statement finds any items that do not match, our function will end right at that moment. No more code will be executed.
When you add that else statement, it means that if there are any items that do match, the function will return True and no more code will be executed.
The first and the second code you proposed give different outputs.
And you should know that functions can use return only once.
What helps is to print out intermediate results.
1
def reversed_list(lst1, lst2):
for index in range(len(lst1)):
print(index)
if lst1[index] != lst2[len(lst2)-1-index]:
print('False')
return False
print('True')
return True
2
def reversed_list(lst1, lst2):
for index in range(len(lst1)):
print(index)
if lst1[index] != lst2[len(lst2)-1-index]:
print('False')
return False
else:
print('True')
return True
Run my code with the added lines that prints you intermediate results. You will see that the second function will only iterate over the first element and then return either True or False.
In the first case return True is the end of your function. You have to iterate through the whole range(len(lst1)) in order to reach it. So if the condition of the ifin the loop is matched, the return False statement is executed and the function ends there.
In your second case, you never iterate through the whole list. At the first iteration, you check the condition lst1[index] != lst2[len(lst2)-1-index] where index = 0 and return a True or a False.
Related
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 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.
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.
def is_prime(x):
if x < 2:
return False
elif x == 2:
return True
for i in range(2,x):
if x % i == 0:
return False
break
else:
return True
The above code is mine from codecademy's python course, and i get a prompt telling me that when 9 is passed to the argument, the function returns True instead of False. I can fix this by doing:
for i in range(2,x):
if x % i == 0:
return False
break
return True
I don't understand why the second bit of code works, and why the first bit doesn't. In fact, I would have thought the second bit of code wouldn't work: If the argument was 9, then when i == 3, x % i == 0. So the function gets a returned value of False, and the loop breaks. However, since the "return True" is NOT within the for loop, then after exiting the for loop, "return True" will execute anyway, so regardless of the input, the function will get returned a value of True, since that's the last line of code to be executed within the function?
Following that line of reasoning, I believed that my initial code would work, because if "return True" was within the for loop, then the break command would be executed (assuming the input was 9), AFTER the function has been returned a value of False. And since the "return True" line is within the the for loop, and since the break command will exit the for loop, then the last value given to the function would have been False, which would have been correct?
I apologise in advance if I have (very likely) misused certain terms, of have some flaw in my understanding of how the code works or is executed. I just can't seem to get my head around why the second bit of code works, but the first bit doesn't.
Cheers!
The for loop starts with i == 2. 9 % 2 == 1, so it goes into the else: branch, and returns True.
Only if the entire loop is run and none of the numbers divided 9 should you return True.
Also, following return ... by break is useless - the function has already returned, so that break statement is never reached.
That's also the answer to your last question -- when return is executed, this function ends. Nothing else is done anymore, and the program continues (returns to) wherever it was when it called the function.
The first version didn't work because , when ever the if condition is false it returns True.Thus, when x==9 and i==2, 9%2!=0, thus it returns true. Also, no need to use break statement as return statement returns the value from function and loop doesn't continue after return.
Following is the correct code
def is_prime(x):
if x < 2:
return False
elif x == 2:
return True
for i in range(2,x):
if x % i == 0:
return False
return True
I'm having trouble with this CodingBat problem:
Given an int array length 2, return True if it contains a 2 or a 3.
I've tried two different ways to solve this. Can anyone explain what I'm doing wrong?
#This one says index is out of range, why?
def has23(nums):
for i in nums:
if nums[i]==2 or nums[i]==3:
return True
else:
return False
#This one doesn't past the test if a user entered 4,3.
#It would yield False when it should be true. Why?
def has23(nums):
for i in nums:
if i==2 or i==3:
return True
else:
return False
Your first one doesn't work because the for loop in Python isn't the same as the for loop in other languages. Instead of iterating over the indices, it iterates over the actual elements.
for item in nums is roughly equivalent to:
for (int i = 0; i < nums.length; i++) {
int item = nums[i];
...
}
Your second one doesn't work because it returns False too soon. If the loop encounters a value that isn't 2 or 3, it returns False and doesn't loop through any other elements.
Change your loop to this:
def has23(nums):
for i in nums:
if i == 2 or i == 3:
return True # Only return `True` if the value is 2 or 3
return False # The `for` loop ended, so there are no 2s or 3s in the list.
Or just use in:
def has23(nums):
return 2 in nums or 3 in nums
Another way to do the above using index
A variation for learning purpose
def has23(nums):
try :
alpha = nums.index(2)
return True
except:
try:
beta = nums.index(3)
return True
except:
return False
Old post, I know, but for future readers:
Regarding the for loop, I think it's worth mentioning another option: using the range() function.
Instead of
for i in nums:
You can switch the for loop to look like so:
for i in range(len(nums)):
This will iterate over integers, the same as other languages do.
Then using nums[i] will get the value of the index.
However, I notice another problem with your code and its stated objectives:
within the for loop, all execution paths return a variable. It will only go through the for loop once, regardless of the length of the array, because after the first execution it returns, ending the function's execution. If the first value is false, the function will return false.
Instead, you would want to end the execution within the loop only if the statement is true. If the loop goes through all posibilities and nothing is false, then return false:
def has23(nums):
for i in range(len(nums)): # iterate over the range of values
if nums[i]==2 or nums[i]==3:# get values via index
return true # return true as soon as a true statement is found
return false # if a true statement is never found, return false
This Java code works fine:-
public boolean has23(int[] nums) {
if(nums[0]==2||nums[1]==2||nums[0]==3||nums[1]==3){
return true;
}
return false;
}
def has23(nums):
if nums[0] ==2 or nums[0]==3 or nums[1] ==2 or nums[1]==3:
return True
else:
return False