How to initialize a tuple in Python using recursion - python

I'm working on course work for school, the problem is as follows,
The elements of tuple can be initialized so that tup[i] == i in a recursive fashion as follows:
A tuple of size 0 is already initialized
Otherwise:
set the last element of the tuple to n-1 (where n is the number of elements in the tuple)
initialize the portion of the tuple consisting of the first n-1 elements
Write a function named init that takes one argument, a tuple of the proper length, and returns an tuple initialized as described above.
def init(tupin):
if len(tupin) == 0:
return tupin
else:
return (0,) + init(tupin[1:])
so far this is all I have been able to get.

You skipped the step set the last element of the tuple to n-1. You can do that by appending (len(tupin)-1,).
def init(tupin):
if len(tupin) == 0:
return tupin
else:
return init(tupin[1:]) + (len(tupin)-1, )

Maybe like this:
def init(tupin):
if not isinstance(tupin, tuple):
raise TypeError("Please, supply a tuple to the function")
if len(tupin):
return init(tupin[:-1]) + (len(tupin)-1,)
else:
return tupin

Related

Find the number from the set that is not present in the array

I was given this question in an interview: You are given a set of numbers {1..N} and an array A[N-1]. Find the number from the set that is not present in the array. Below is the code and pseudocode I have so far, that doesn't work.
I am assuming that there is one (and only one) number in the set that isn’t in the array
loop through each element in the set
loop through each element in the array O(n)
check to see if the number is in the array
if it is, do nothing
else, early return the number
def findMissingNo(arr, s):
for num in s: #loop through each element in the set
for num2 in arr: ##loop through each element in the array O(n)
if (num == num2): #if the number in the set is in the array, break
break
print (num)
return num #if the number in the set is not in the array, early return the number
return -1 #return -1 if there is no missing element
s1 = {1,4,5}
arr1 = [1,4]
findMissingNo(arr1, s1)
By defination, we have a set from 1 to N and a array of size N-1 , contains numbers from 1 to N , with one number missing and we have to find that number
since only 1 number is missing, and set has n element and array has n-1 element. so array is subset of set, with missing element as missing, that means
all_number_of_set = all_number_of_array + missing_number
also
sum_of_all_number_of_set = sum_of_array_number + missing_number
which implies
missing_number = sum_of_all_number_of_set - sum_of_array_number
pseudo code
def findMissingNo(set_, arr_ ):
return sum(set_) - sum(arr_)
If I understood your question well then you are finding the efficient way of finding the set number that do not exist in list. I see you are inner looping which would be O(n^2). I would suggest to make the dict for the list which would be O(n) then find O(1) element in dictionay by looping over set O(n). Considering large list with subset set:
def findMissingNo(arr_list, s_list):
d = dict()
for el in arr_list:
d.update({el: el})
for s in s_list:
try:
d[s]
pass
except KeyError:
return s
return -1
s1 = {1,4,5}
arr1 = [1,4]
findMissingNo(arr1, s1)
Hope it helps:)
Your function is quadratic, because it has to check the whole list for each item in the set.
It's important that you don't iterate over the set. Yes, that can work, but you're showing that you don't know the time complexity advantages that you can get from a set or dict in python (or hashtables in general). But you can't iterate over the list either, because the missing item is ... missing. So you won't find it there.
Instead, you build a set from the list, and use the difference function. Or better, symmetric_difference (^) see https://docs.python.org/3.8/library/stdtypes.html#set
def findMissingNo(arr, s):
d = set(arr) ^ s # symmetric difference
if 1 == len(d):
for item in d:
return item
print (findMissingNo([1,4], {1,4,5}))
5
I took a few shortcuts because I knew we wanted one item, and I knew which container it was supposed to be in. I decided to return None if no item was found, but I didn't check for multiple items.
What about something like:
def findMissingNo(arr, s):
for num in s: # loop through each element in the set
if num in arr:
pass
else:
return num # if the number in the set is not in the array, early return the number
return -1 # return -1 if there is no missing element

How to get minimum odd number using functions from list

I'm trying to get the minimum odd number using python. I used lambda, loops and other methods to get minimum odd number but i was not able to get that using functions. here is my code
z= [1,8,-4,-9]
def min_odd(x):
for i in x:
if (i%2!=0):
return min(i)
y = min_odd(z)
print (y)
Can some please tell me what i was missing here.
The min() function expects an iterable like a list which it will then yield the smallest element from.
E.g. min([1,0,3]) gives 0.
So if you want to use it, you must create a list (or other iterable) of the odd numbers that you can then pass into it:
def min_odd(x):
odds = []
for i in x:
if i % 2 != 0:
odds.append(i)
return min(odds)
note that we could also use a list-comprehension:
def min_odd(x):
return min([i for i in x if i % 2 != 0])
which both work.
An alternative method would be to store the current minimum odd value in a variable and update this variable if we come across a smaller odd value:
def min_odd(x):
min_v = float('inf')
for i in x:
if i % 2 != 0 and i < min_v:
min_v = i
return min_v
Try:
min([val for val in z if val % 2 != 0])
It seems your code logics are wrong. First off, you seem to have an indentation error in the return statement. Second off, the min() function requires a collection of items (like an array for example) or a series of arguments to determine the minimum in that series. You can try multiple things.
Use another variable to store a temporary minimum. Replace it every time you find a smaller odd value ( for every i in x... if the value is odd and is smaller than the previous odd value, replace it) and have it started with the first odd number you can find.
Take all the odd numbers and add them to another array on which you will apply the min function.
Hope this proves useful!
You could pass a generator into the min() function:
def min_odd(iterable):
return min(i for i in iterable if i % 2)
I didn't write i % 2 != 0 because any odd number will return 1 which has a Boolean value of True.
I added a parameter to the function that takes the iterable so it can be used for any iterable passed in.
min operates on an iterable. i is not an iterable in your code; it's the last element of the list.
You can achieve what you want with a filter, though:
min(filter(lambda e: e%2 != 0, x))

Why does this recursive function exceed maximum length in python?

#finds length of a list recursively, don't understand why it exceeds maximum length, can someone please explain?
def lengtho(xs):
if(xs == None):
return 0
return 1 + lengtho(xs[1:])
lengtho([1,2,3,4,1,4,1,4,1,1])
When the code reaches the end of the list (the base case), xs will be equal to [] (the empty list), not None. Since [][1:] simply returns [], the function will call itself until the stack overflows.
The correct way to write this function in python would be:
def lengthof(xs):
"""Recursively calculate the length of xs.
Pre-condition: xs is a list"""
if (xs == []):
return 0
else:
return 1+ lengthof(xs[1:])
Your base case of recursion will never get to True value, xs == None will be always False if you are talking about lists, probably you want to change it to xs == [] or just if not xs

Recursion- removes duplicates from the list

The question is to write a recursive function that Removes duplicates from the list.
Hint: it can be implemented with two auxiliary functions.
The list contains one and only one of each value formerly present
in the list. The first occurrence of each value is preserved.
Implement and test a recursive version of this method
def clean(self):
key_node = self._front
while key_node is not None:
# Loop through every node - compare each node with the rest
previous = key_node
current = key_node._next
while current is not None:
# Always search to the end of the list (may have > 1 duplicate)
if current._value == key_node._value:
# Remove the current node by connecting the node before it
# to the node after it.
previous._next = current._next
self._count -= 1
else:
previous = current
# Move to the _next node.
current = current._next
# Check for duplicates of the _next remaining node in the list
key_node = key_node._next
return
And this is what I have so far, I don't understand what is auxiliary functions:
def clean(list):
i = 1
if len(list) == 0:
return []
elif len(list) == 1:
return list
elif list[i] == list[i-1]:
del list[i]
return clean(list[i:])
Example: for list = [1,2,2,3,3,3,4,5,1,1,1], the answer is [1,2,3,4,5,1]
Here is one function that calls a another, recursive function and produces the result you want. I suppose you could call clean2 an auxiliary function, although, like you, I don't know exactly what that's supposed to mean. It's a rather ridiculous piece of code but it doesn't use any standard library functions and it modifies x in place. I would expect it to be horribly inefficient. If I wrote this for my day job I'd probably resign.
def clean(x):
clean2(x, 1)
def clean2(x, i):
if i >= len(x):
return
if x[i] == x[i - 1]:
del x[i]
clean2(x, i)
else:
clean2(x,i+1)
the_list = [1,2,2,3,3,3,4,5,1,1,1]
clean(the_list)
print(the_list)
>>> [1,2,3,4,5,1]
Here's a recursive definition using an auxiliary function go to actually implement the recursion. The idea is that the outer clean function can take any iterable object (e.g. a list) and it always produces a list of values:
def clean(iterable):
def go(iterator, result):
try:
x = next(iterator)
if result == [] or result[-1] != x:
result.append(x)
return go(iterator, result)
except StopIteration:
return result
return go(iter(iterable), [])
clean just invokes a locally-defined go function, passing an iterator and the eventual result value (initially an empty list). go then tries to advance the iterator and compares the referenced value with the end of the result: if it's different (or if the result is empty), the value is appended. go then recurses.

Python: Unable to check for duplicates using list indexes

For some reason the same method is working for one function and not the other. The function that works already is defined as the following:
def is_unique1(lst):
for item in lst:
current_index = lst.index(item)
if lst[current_index] in lst[current_index + 1:-1]:
return False
return True
You pass in a list and checks the uniqueness of it, if it is unique then return TRUE if not return FALSE. However I am then asked to create another function, except this time copy the list and sort it. Then iterate over every index for values in the list to check whether the value at that index is equal to the value at the next higher index. But it keeps returning TRUE no matter what input. The function looks like this:
def is_unique2 ( myList ):
list_copy = list(myList)
list_copy.sort()
print(list_copy)
for item in list_copy:
index = list_copy.index(item)
if list_copy[index] in list_copy[index + 1: -1]:
return False
return True
Why is this happening. Am I using the slice incorrectly. I am checking if the current value at list_copy[index] is in the index + 1. I am testing it like so:
print('\nTesting is_unique2')
print (is_unique2(['raisin', 'apricot', 'celery', 'carrot']) )
print (is_unique2(['raisin', 'apricot', 'raisin', 'carrot']) )
Your bug is that by checking if list_copy[index] in list_copy[index + 1: -1] you're not checking the very last item in the list.
Remember, in Python, it's always "upper bound excluded": so somelist[a:b] will span somelist[a] included to somelist[b] excluded... for any a and b.
Easy fix: use in list_copy[index + 1:]. IOW, give no upper bound for the slice, so the slice will run all the way to the end of the list.
Incidentally, your approach is very dubious if the list's items are hashable -- in which case,
def is_unique3(myList):
return len(myList) == len(set(myList))
will be much faster and much less bug-prone too:-)
Try this line instead of your -1 indexed list for unique1:
lst[current_index] in lst[current_index + 1:None:-1]:

Categories

Resources