Here's the problem.
This is part of the List-2
Medium python list problems -- 1 loop.
Given an array of ints, return True if the array contains a 2 next to a 2 somewhere.
has22([1, 2, 2]) → True
has22([1, 2, 1, 2]) → False
has22([2, 1, 2]) → False
I was getting the error "list index is out of range" at first
I know where I was going wrong on line 4 of the original problem because once it is at the last number in the list it cannot add one anymore.
I have provided my original code below. The first code block was when I was getting the error "index out of range". The second solution works but I am wondering if there is a cleaner way of writing it.
Also on CodingBat when I run my solution it says "Other Tests" Failed at the bottom but no example I'm not sure what that means.
Thanks
Here's my code block - FIRST TRY:
def has22(nums):
for i in range(len(nums)):
first = nums[i]
second = nums[i+1]
if first == second:
return True
MY SOLUTION:
def has22(nums):
size = len(nums)
for i in range(len(nums)):
first = nums[i]
if size >= i+2:
second = nums[i+1]
if first == second:
return True
return False
So if the question is whether the solution can be written cleaner, I think something like this should work:
def has22(nums):
return (2, 2) in zip(num, num[1:])
and it looks pretty clean.
A little bit of explanation - zip creates pairs of values from 2 lists, so I just slice the input list into 2, where in the second list I omit the first element. Then I simply check whether tuple 2, 2 exists in the zipped pairs.
BTW I just noticed a bug in your solution - it returns True for input e.g. [2, 1] (basically any input, where 2 is second to last. So to fix this bug, and preserve the original "idea" of your solution, you could write it like this:
def has22(nums):
for i, el in enumerate(nums):
if el == 2 and i + 1 < len(nums) and nums[i + 1] == 2:
return True
return False
enumerate is the preferred way of iterating through a list with indices.
#here is the code
def has_33(nums):
for i in range(0,len(nums)-1):
if nums[i:i+2]==[3,3]:
return True
return False
nums = [1,2,3,3]
print(has_33(nums))
questions:
why the code used len(nums)-1 in second line?(why used -1 ?)
in the 3rd line why do they used [i:i+2]==[3,3] and how does this code perform ?
please let me know ,
i am basically a noob in coding right now please help me to under stand how this code works
If you're looking for two elements in a row, there's no point in checking the last element of the list, since there's nothing after it. So the loop stops at the 2nd-to-last index.
nums[i:i+2] returns a slice of the list from element i to element i+1. Those are 2 consecutive elements. Then it compares this to [3, 3] to see if that pair of elements are two 3's next to each other.
Because a list of the length n has only n-1 pairs (for example, [1,2,3,4] has [1,2], [2,3] and [3,4])
Beacuse list[x:y] does not return element y of the list.
The following code is simple and should work for what you want to do.
a=[0, 1, 2, 0, 3]
def has_33():
last_i = 0
for i in a:
if last_i==3 and i==3:
return True
if i==3:
last_i = 3
return False
print(has_33())
Also works in different combinations of ...3,3...
So my recursive function is too look in a list and see if an item is repeated in a list already. Ex. L = [1,2,3,4,3] return True. I've completed it but im not allowed to use the 'in' function but dont know a work around.
Edit: the only built in functions i am allowed to use are len, and the index and splice operators.
def has_repeats(L):
if L == []:
return False
elif L[0] in L[1:]:
return True
else:
return has_repeats(L[1:])
return False
You may consider using recursion to compare the list in reversed order that their indexes are the same, since index at default returns the first occurrence, like this:
def has_repeats(L):
if len(L) <= 1:
return False
if L.index(L[-1]) != len(L) - 1:
return True
return has_repeats(L[:-1])
Usage:
has_repeats([1, 2, 3, 4, 3])
True
has_repeats([1, 2, 3, 4, 0])
False
So basically check the index of last item len(L) - 1 will be the same as L.index which should return the first occurrence, if they don't match, there is a duplicate before the last item, and do it recursively.
An alternative is to compare the first and last elements in the list, progressively discarding from both ends.
def has_repeats(L):
if len(L) < 2:
return False
return L[0] == L[-1] or has_repeats(L[:-1]) or has_repeats(L[1:])
This is inefficient because of the double recursion, but it works for short lists.
def array_front9(nums):
end = len(nums)
if end > 4:
end = 4
for i in range(end):
if nums[i]==9:
return True
return False
I need to understand the above python code and why two return statement in 'for loop'. This is seriously confusing me.
This could be rewritten much simpler (that is, "more pythonic") as this:
def array_front9(nums):
return 9 in nums[:4]
The first half of the code is setting the loop limit to the first 4 elements, or less if the array nums is shorter. nums[:4] does essentially the same thing by creating a copy that only contains up to the first 4 elements.
The loop is checking to see if the element 9 is found in the loop. If found, it returns immediately with True. If it's never found, the loop will end and False is returned instead. This is a longhand form of the in operator, a built-in part of the language.
Let me explain:
def array_front9(nums): # Define the function "array_front9"
end = len(nums) # Get the length of "nums" and put it in the variable "end"
if end > 4: # If "end" is greater than 4...
end = 4 # ...reset "end" to 4
for i in range(end): # This iterates through each number contained in the range of "end", placing it in the variable "i"
if nums[i]==9: # If the "i" index of "nums" is 9...
return True # ...return True because we found what we were looking for
return False # If we have got here, return False because we didn't find what we were looking for
There are two return-statements in case the loop falls through (finishes) without returning True.
The second return isn't in the for loop. It provides a return value of False if the loop "falls through", when none of nums[i] equal 9 in that range.
At least, that's how you've indented it.
You could rewrite this to be more clear using list slicing:
def array_front9(nums):
sublist = nums[:4]
if 9 in sublist:
return True
else:
return False
I'm trying to do a lab work from the textbook Zelle Python Programming
The question asked me to "write and test a recursive function max() to find the largest number in a list. The max is the larger of the first item and the max of all the other items." I don't quite understand the question from the textbook.
def Max(list):
if len(list) <= 1:
else:
return list[0]
else:
m = Max(list[1:])
return m if m > list[0] else list[0]
def main():
list = eval(raw_input(" please enter a list of numbers: "))
print("the largest number is: ", Max(list))
main()
Or maybe I'm suppose to open a txt file with numbers in it and then use recursive?
I believe recursive works like this
def function()
> if something:
>>return 0
>else:
>>return function()
Your understanding of how recursion works seems fine.
Your if-block is messed up, you have two elses to one if and the alignment is out. You need to remove your first else and un-indent everything below the if one level. eg:
def Max(list):
if len(list) == 1:
return list[0]
else:
m = Max(list[1:])
return m if m > list[0] else list[0]
def main():
list = eval(raw_input(" please enter a list of numbers: "))
print("the largest number is: ", Max(list))
main()
I post a different solution approach of the problem. Most of the answers manipulate the list using the slice operator in each recursive call. By the time the exercise does not provide a strict function prototype to be used, I also pass as function parameter the length of the list.
Suppose that we try to find and return the maximum element from a sequence S, of n elements.
Function prototype: Max(S, n)
Base case: If S contains only one item, return it. (Obviously the only item in the sequence is the max one.)
Recur: If not the base case, call Max each time for one less item, that is call Max(S, n-1). We then store the returning value to a variable called previous that indicate the previous element from the sequence and check that value with the next element in the sequence, which is the right most element in the current recursive call, and return the max of these values.
A recursion trace of the above procedure is given in the following figure. Suppose we try to find the max from a list that contains [5, 10, 20, 11, 3].
Note: To help you further, keep in mind that we recursively iterate the list from the right most element to the left most one.
Finally here is the working code:
def find_max_recursively(S, n):
"""Find the maximum element in a sequence S, of n elements."""
if n == 1: # reached the left most item
return S[n-1]
else:
previous = find_max_recursively(S, n-1)
current = S[n-1]
if previous > current:
return previous
else:
return current
if __name__ == '__main__':
print(find_max_recursively([5, 10, 20, 11, 3], 5))
Note: The recursive implementation will work by default only with sequences of 1000 most elements.
To combat against infinite recursions, the designers of Python made an
intentional decision to limit the overall number of function
activations that can be simultaneously active. The precise value of
this limit depends upon the Python distribution, but a typical default
value is 1000. If this limit is reached, the Python interpreter
raises a RuntimeError with a message, maximum recursion depth exceeded.
Michael T. Goodrich (2013), Data Structures and Algorithms in Python, Wiley
To change the default value do:
import sys
sys.setrecursionlimit(1000000)
here is one more approach to solve above problem
def maximum(L):
if len(L) == 1:
return L[0]
else:
return max(L[0],maximum(L[1:]))
so example input and output:
L= [2,4,6,23,1,46]
print maximum(L)
produces
46
The basic approach is this.
If the list contains only a single element, that element is the max. Return it immediately.
Otherwise, the list contains multiple elements. Either the first element in the list is the maximum, or it is not.
The maximum of the first element is simply the first element in the list.
Recursively call Max on the rest (all but first element) to find the maximum of those elements.
Compare the results from step 3 and 4. The result is the number that is greater. Return it.
Right now you have some syntax errors. For example, you have two else clauses for a single if, and the indentation looks funny. You can only have one else for an if block. But if you follow these instructions, you should have a working algorithm.
def Max(lis,maxx=-float("inf")):
if len(lis) == 1: #only one element in lis
return maxx if maxx>lis[0] else lis[0] #return lis[0] if it's greater than maxx
else:
m=lis[0] if lis[0]>maxx else maxx # m = max(lis[0],maxx)
return Max(lis[1:],m) #call Max with lis[1:] and pass 'm' too
print Max([1,2,39,4,5,6,7,8]) #prints 39
print Max([1,2,3,4,5,6,7,8]) #prints 8
These solutions fail after certain list size.
This is a better version:
def maximum2(a, n):
if n == 1:
return a[0]
x = maximum2(a[n//2:], n - n//2)
return x if x > a[0] else a[0]
def maximum(a):
return maximum2(a, len(a))
maximum(range(99999))
>>> 99998
One simple way would be to sort the list first then use indexing.
Here's a function that would work:
a = [1,233,12,34]
def find_max(a):
return sorted(a)[-1]
def find_max(my_list, max):
if len(my_list) <= 1:
return max
else:
if my_list[0] > max:
return find_max(my_list[1:], my_list[0])
else:
return find_max(my_list[1:], max)
if __name__ == '__main__':
my_list = [1, 5, 16, 9, 20, 40, 5]
print(find_max(my_list, my_list[0]))
def find_max(arr):
"""find maximum number in array by recursion"""
if arr == []: # if its an empty array
return 0
if len(arr) == 1: # if array has only one element
return arr[0]
else: # get max of first item compared to other items recursively
return max(arr[0], find_max(arr[1:])) # 1: means all other excluding 0th element
def main():
print(find_max([2,3,5,6,7,1])) # will print max - 7
if __name__ == "__main__":
main()
You can also do it in this way:
def maximum(data, start, stop):
if start >= stop:
return data[start]
else:
if data[start] >= data[stop - 1]:
return maximum(data, start, stop - 1)
else:
return maximum(data, start + 1, stop)
def recursiveMax(a):
if len(a) == 1:
return a[0]
else:
return a[0] if a[0] > recursiveMax(a[1:]) else recursiveMax(a[1:])
Test:
print(recursiveMax([1, 2, 15, 6, 3, 2, 9]))
print(recursiveMax([98, 2, 1, 1, 1, 1, ]))
TLDR; This code will also work when the list passed to the function is empty!
#jam's answer is amazing. However, I found some problems with the conditions, I think #Blender was hinting at it.
That code will fail in the case when the list passed to the function is empty. There are two base cases:
When the list is empty -> return None
When the list has one item -> return list[0]
And then the recursive case ... to reduce any other case into the base case.
def recursive_max(arr):
if len(arr) == 0:
return None
elif len(arr) == 1:
return arr[0]
else:
maxItem = recursive_max(arr[1:])
return maxItem if maxItem > arr[0] else arr[0]
Here is my answer, with a one line of code :))
def max_value(n_list):
return n_list[0] if len(n_list) == 1 else max(n_list[0], max_value(n_list[1:]))
def getMaxNumber(numbers):
return 'N.A' if len(numbers) == 0 else max(numbers)