how to find largest number in a list using recursion? - python

def find_highest(lst):
if lst[0] < lst[-1]:
return find_highest(lst.pop(0))
elif lst[0] > lst[-1]:
return find_highest(lst.pop())
else: return lst
This code raises TypeError.
Can anyone tell why is this happening?

You code has the problem that it will raise IndexError. You are pulling elements out of the list using pop, so at some point the list will be empty.
You should check for the list length.
Here you have the solution using a different approach - I still use pop but always on the same end of the list. -
def find_largest(target_list):
# If the len of list is 0, we have consume all numbers.
if len(target_list) == 0:
return None
# Just get a number from the list, no matter which ...
number = target_list.pop()
# ... then recursively call the function to get the largest among the
# remaining numbers in the list.
largest = find_largest(target_list)
# Compare the number you pull out the list with the "largest" of the remaining and
# keep the largest.
if largest is None or number >= largest :
return number
return largest
if __name__ == "__main__":
import random
target_list = [random.randint(0, 10) for i in range(10)]
print(f"Target list: {target_list}")
largest = find_largest(target_list)
print(f"Largest number: {largest}")

Related

Looping through a list and finding when numbers stop increasing at the same rate

I have a list of numbers that initially increase at the same rate. For example:
[0,3,6,9,12,15,18...]
However, when reaching a certain point in the list, the increase in value actually increases.
[0,3,6,9,12,15,18...150,156,162,168,174...240]
I want to loop over this list and create two new lists. One where the number increases by 3, and one when the numbers begin to increase by 6. However, I am not sure how exactly to write the code that detects when this change occurs.
Expected result:
[0,3,6,9,12,15,18...,147]
[150,156,162,168,174...240]
def splitList(list):
if(len(list) < 2):
return [], []
listX = []
listY = []
dif = list[1] - list[0]
for e in list:
if(e == list[0]):
listX.append(e)
elif(e - listX[len(listX)-1] == dif):
listX.append(e)
else:
listY.append(e)
return listX, listY
Check this?
test_list=[0,3,6,9,12,15,18,21,27,33,39,45] #=== List
list_3=[]
list_6=[]
new_list=[]
for j,i in enumerate(test_list): #=== Gives index number for each element in the list
try: #== Check for exceptions, if one occurs, goes to 'except:' statement
op=test_list[j+1] #== Get the elements from index position 1 ahead of the current ome
if op-3==i: #== check if the the difference is 3
list_3.append(i)
elif op-6==i: #== check if the the difference is 6
list_6.append(i)
except:
pass
new_list.append(list_3)
new_list.append(list_6)
print(new_list)

How To Modify This Code In python to return/print all positive numbers not just one

The positive_numbers function should return a list containing numbers that are non-negative (>=0).
However, currently, it returns only the [3] instead of a list of values.
I tried different ways to make this work I'm currently a beginner in python and I don't have anyone to ask that's why I'm sorry if this is too basic for you just want to learn and see my mistake
def positive_numbers(numbers):
for number in numbers:
result = []
result = result + [number]
if number < 0:
continue
return result
Expected: The function should return a list of numbers
Actual: returns list with the only value being 3
Error: The call positive_numbers([1, 2, 3]) should return [1, 2, 3], but it returned [3]
You reset the list each iteration of the loop because of result = [].
Try this:
def positive_numbers(numbers):
result = []
for number in numbers:
if number > 0:
result = result + [number]
return result
Also, debugging would make this very clear. Try to debug your code to get a better understanding of it.
You have to declare result outside of your for loop.
def positive_numbers(numbers):
result = []
for number in numbers:
if number < 0:
continue
result.append(number)
return result
As already stated, you are setting results no a new empty string at every iteration of your for loop. Also, the if statement does not make any change, since by the time is evaluated, the new number is appended to the result.
So the minimal working change is:
def positive_numbers(numbers):
result = []
for number in numbers:
if number 0:
continue
result = result + [number]
return result
Besides, note that you could use a list comprehension for that:
positive_numbers = [number for number in numbers if number >= 0]
Or using filter:
positive_numbers = list(filter(lambda num: num>=0, numbers))
Note that in the latter case, if you don't need your output to be a list but an iterable, you can remove the list(...) part
You have all of the pieces, just not necessarily in the right order. Here is an amended version:
def positive_numbers(numbers):
result = []
for number in numbers:
if number < 0:
continue
result = result + [number]
return result
With result = [] inside the for loop as you had it, you were emptying the result on each iteration. Then you were unconditionally adding the number to the list instead of checking if it is negative first. In this amended first, the loop skips to the next number if the current number is not non-negative.

Find the Duplicate Number

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
My solution:
def findDuplicate(nums):
slow = fast = finder = 0
while fast is not None:
slow = nums[slow]
fast = nums[nums[fast]]
if fast is slow:
return slow
return False
nums = [1,2,2,3,4]
print findDuplicate(nums)
My above solution works and gives me o/p 2 but it doesn't work for every input for example it doesn't work for [11,15,17,17,14] or [3,1,2,6,2,3] and gives me error IndexError: list index out of range. I am not able to find patterns and am not able to track down the exact problem. Also tried to change my while condition:
while fast is not None and nums[nums[fast]] is not None:
your help will be greatly appreciated! Thank you.
Since the numbers are between 1 and n and you have been told there is only one duplicate, you can use difference between the sum of the numbers in the array and the sum of numbers from 1 to n to get the duplicate.
def findDuplicate(l):
n = len(l) - 1 # Get n as length of list - 1
return sum(l) - (n * (n + 1) / 2) # n*(n+1)/2 is the sum of integers from 1 to n
So the duplicate is the sum of the list - n*(n+1)/2
Of course, this doesn't generalize to finding duplicates for any list. For that case, you need to use #Jalepeno112 's answer.
The fact that the first one works is a fluke. Let's look at what it does on the first pass.
nums = [1,2,2,3,4]
# slow starts as index 0. So now, you've reassigned slow to be nums[0] which is 1.
# so slow equals 1
slow = nums[slow]
# now you are saying that fast equals nums[nums[0]].
# nums[0] is 1. nums[1] is 2
# so fast = 2
fast = nums[nums[fast]]
On the next pass, slow will be nums[1] which is 2. fast will be nums[nums[2]] which is nums[2] which is 2. At this point slow and fast are equal.
In your second example, you are getting an IndexError because of fast = nums[nums[fast]] If the value at nums[fast] is not a valid index, then this code will fail. Specifically in the second example, nums[0] is 11. nums doesn't have an element at index 11, so you get an error.
What you really want to be doing is performing a nested for loop on the array:
# range(0,len(nums)-1) will give a list of numbers from [0, to the length of nums-1)
# range(1, len(nums)) does the same,
# except it will start at 1 more than i is currently at (the next element in the array).
# So it's range is recomputed on each outer loop to be [i+1, length of nums)
for i in range(0,len(nums)-1):
for j in range(i+1,len(nums)):
# if we find a matching element, return it
if nums[i] == nums[j]:
return nums[i]
# if we don't find anything return False
return False
There are likely other more Pythonic ways to achieve this, but that wasn't your original question.
first you must ensure all numbers in list satisfy your constrains.
to find duplicated numbers in a list Use Counter in collections it will return each number and number of occurrence example :
>>> from collections import Counter
>>> l=Counter([11,15,17,17,14])
>>> l
Counter({17: 2, 11: 1, 14: 1, 15: 1})
to get the most common one use :
>>> l.most_common(n=1)
[(17, 2)]
where n is the number most common numbers you want to get
def duplicates(num_list):
if type(num_list) is not list:
print('No list provided')
return
if len(num_list) is 0 or len(num_list) is 1:
print('No duplicates')
return
for index,numA in enumerate(num_list):
num_len = len(num_list)
for indexB in range(index+1, num_len):
if numA == num_list[indexB]:
print('Duplicate Number:'+str(numA))
return
duplicates([11,15,17,17,14])
duplicates([3,1,2,6,2,3])
duplicates([])
duplicates([5])
l=[]
n= int(input("the number of digit is :"))
l=[0 for k in range(n)]
for j in range(0,n):
l[j]=int(input("the component is"))
print(l)
b=0; c=0
for i in range(n):
if l[i]== l[n-1-i]:
b=1;c=i
if b==1:
print("duplicate found! it is",l[c])
elif b==0:
print("no duplicate")
The answer is unfinished. It tries to convert the array to a linked list. So far it found where the slow pointer and fast pointer met, but this is the halfway solution. To get the solution, we need to initialize another pointer from the beginning of the linked list and walk towards each other. When they meet, that point is the where cycle is detected, in our question it is where the single point is:
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
slow,fast=0,0
while True:
slow=nums[slow]
fast=nums[nums[fast]]
if slow==fast:
break
slow2=0
while True:
slow2=nums[slow2]
slow=nums[slow]
if slow==slow2:
return slow2

Getting First Prime in a List of Random Numbers

I was playing around with the Python shell and I have what I believe is an extremely naive implementation of a function that simply returns the first prime number in a list of 100 randomly generated numbers (whose values are between 0 and 99, inclusive). Code below:
>>> def is_prime(n):
if n < 2:
return False
elif n == 2:
return True
for i in range(2, n):
if n % i == 0:
return False
return True
>>> from random import randint
>>> numbers = []
>>> for i in range(0, 100):
numbers.append(randint(0, 99))
>>> def get_first_prime(values):
temp = []
for i in values:
if is_prime(i):
temp.append(i)
return temp[0]
>>> get_first_prime(numbers)
I want this function to strictly return only the first prime number. My implementation uses a helper list to cache all primes and then simply return the element at the first index. It works, but I'm not convinced it's a good one. I'm sure there is a more efficient way of doing this that does not require scanning through the entire list, but I can't seem to think of one yet.
What are some better alternatives?
def get_first_prime(values):
for i in values:
if is_prime(i):
return i
This way you don't keep searching once you find a prime. The function implicitly returns None if no prime is found.
Yes, you do not even need to generate a list of all the random numbers, you can test each one as they are generated, and return as soon as you've found one.
from random import randint
import math
def is_prime(n):
if n < 2:
return False
elif n == 2:
return True
for i in range(2, int(math.sqrt(n) + 1)):
if n % i == 0:
return False
return True
def get_first_prime(number):
for i in range(number + 1):
n = randint(0, 99)
if is_prime(n):
return n
get_first_prime(100)
You are right. Your code not only has more time complexity (running through all the list elements even after finding the first prime) and space complexity (temp list to hold all the primes) but also stands a risk of throwing IndexError when there are no prime numbers in the list.
So you could mend it in the following manner:
def get_first_prime(values):
for i in values:
if is_prime(i):
return i
Note that when there is no prime in the input the return statement would never get executed that means there is no explicit return; in which case Python returns None. So, if you choose to, you can return the value of your choice at the end of the function outside for loop to indicate 'not found'.
def get_first_prime(values):
for i in values:
if is_prime(i):
return i
return -1
Pythonic way of dealing with this is to raise an Exception and let the caller of the function deal with the exception.
prime = next(filter(isprime, numbers))
See find first element in a sequence that matches a predicate.

Python: Recursive function to find the largest number in the list

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)

Categories