Below is a function which is supposed to return longest palindromic substring of a string. Though the function itself looks alright but for some strange reason It is not returning the string. Any Idea what I am missing here?
def largest(string, repeat=None):
if len(string) <= 1 and repeat:
return repeat[max(repeat.keys())]
elif len(string) <= 1:
return string
list_str = list(string)
repeat = repeat or {}
end_index = -1
while len(list_str)+end_index:
construct = list_str[0:len(list_str)+end_index+1]
reversed_construct = construct.copy()
reversed_construct.reverse()
if construct == reversed_construct:
repeat[len(construct)] = ''.join(construct)
end_index -= 1
string = string[1:]
largest(string, repeat=repeat)
In a order to return a value from a recursive function, one must put return recursive_function(x) so that when a value is returned it is placed in a position where the data can be accessed by the function 'above' it, so to speak.
def Factorial(total,counter):
if counter == 0: #tests whether the counter is at 0
return(total) #if it is at 0 return the product of the consectutive numbers between 0 and starting counter
total *= counter #set the total to itself times the current pass counter
return Recursion(total,(counter-1)) #return the value of this function passing the total and the counter -1
You see that in this example for me to hold the value that was passed previously I have to return it so that after all the recursions are completed they will all pass the data back up the chain of function.
Related
My function is set to return a dictionary. When called, it returns the dictionary. However, if I call the function from within another function, it returns a list.
`
def draw(self, num: int) -> dict:
drawn_dict = {}
if num > len(self.contents):
return self.contents
else:
while num >= 1:
drawn_num = self.contents.pop(random.randint(0, len(self.contents) - 1))
drawn_dict.setdefault(drawn_num, 0)
drawn_dict[drawn_num] +=1
num -= 1
return drawn_dict
def experiment(hat, expected_balls, num_balls_drawn, num_experiments):
matches = 0
full_match = 0
count = 0
print(hat.draw(num_balls_drawn))
print(hat.draw(5))
`
When I call the draw function and print the result, I get the dictionary as expected. But when the draw function is called and result is printed within the experiment function, I get a list.
What is a type of the self.contents? I thing it is the list and this is answer to your question :-)
def draw(self, num: int) -> dict:
drawn_dict = {}
if num > len(self.contents):
return self.contents # <- THIS
else:
while num >= 1:
drawn_num = self.contents.pop(random.randint(0, len(self.contents) - 1))
drawn_dict.setdefault(drawn_num, 0)
drawn_dict[drawn_num] +=1
num -= 1
return drawn_dict
I realized the issue. I was calling the draw function before experiment function, and by calling draw, I was editing the self.contents list which affected its length thereby triggering the "if num> len(self.contents)". So function works as expected when I don't modify the list before actually using it!
Apologies if the title of the question is phrased badly. I am currently trying to make a function that takes in a list of integers from 1 to n, where n is the length of the list. The function should return the first value that is repeated in the list. Duplicates are NOT always next to one another. If one or more integers is less than 1 or if it is not a list, the function should return -1. If there are no duplicates, return 0.
This is my current code:
def find_duplicates(ls):
if type(ls) != list:
return -1
non_dupe = []
i = 0
while i < len(ls):
if ls[i] < 1:
return -1
break
if ls.count(i) > 1:
return i
break
else:
non_dupe.append(i)
i += 1
if len(non_dupe) == len(ls):
return 0
While this code works for a majority of test cases, it doesn't seem to pass
print(find_duplicates([1, 2, 2, 0]))
as it returns 2 instead of the expected -1. I am relatively new to Python and I can't seem to be able to fix this error. I've tried searching for ways to counter this problem but I am not allowed to use for loops to check through a list. Any help is greatly appreciated.
EDIT: I am not allowed to use any of the following but anything else is accepted.
for loops
min() / max()
enumerate() / zip ()
sort()
negative indexing e.g ls[-1]
list slicing
Your code returns a duplicate prematurely; traversing the list, the function first finds 2 as a duplicate, return it, and halts the function immediately. But it has not seen the 0 at the end.
So, you need to let the function see the list all the way towards the end, looking for a negative number. If a negative number is found along the way, you can halt the function. If it does not see a negative number until the end, then let it return the duplicate value:
def find_duplicates(ls):
if not isinstance(ls, list): # check whether ls is a list
return -1
dup = 0
seen = [] # list of numbers seen so far
i = 0 # index
while i < len(ls):
if ls[i] < 1: # if a negative number is found, return -1
return -1
if ls[i] in seen and dup == 0:
dup = ls[i]
seen.append(ls[i])
i += 1
return dup
print(find_duplicates([1, 2, 2, 0])) # -1
print(find_duplicates([1, 1, 2, 2, 3])) # 1
Problem is beacause you are breaking while loop when find a duplicated. In that case, function is finding first the duplicated.
Try this:
def find_duplicates(ls):
if type(ls) is not list:
return -1
duplicated = 0
i = 0
while i < len(ls):
if ls[i] < 1:
return -1
if ls.count(ls[i]) > 1 and duplicated == 0
duplicated = ls[i]
i += 1
return duplicated
Your test case returns 2 because 2 stay at lower indexes comparing to 0.
I would suggest to sort the list before moving on:
def find_duplicates(ls):
if type(ls) != list:
return -1
sorted_list = ls.sorted() #Assign sorted `ls` to another variable, while keeping the order of `ls` intact
non_dupe = []
i = 0
while i < len(ls):
if ls[i] < 1:
return -1
break
if ls.count(i) > 1:
return i
break
else:
non_dupe.append(i)
i += 1
if len(non_dupe) == len(ls):
return 0
Another method I would recommend is using set - a built-in data type of Python. Maybe you should consider trying this approach later on when all test cases are passed. Have a look at this Tutorial for set usage: https://www.w3schools.com/python/python_sets.asp.
You were very close. Try this:
def find_duplicates(ls):
if type(ls) != list:
return -1
non_dupe = []
i = 0
while i < len(ls):
if ls[i] < 1:
return -1
elif ls[i] in non_dupe:
return ls[i]
else:
non_dupe.append(i)
i += 1
return 0
my_list = [1,2,2,0]
result = list(set(filter(lambda x: my_list.count(x) > 1 , my_list)))
# Result => [2]
I hope this solves your problem
So im trying to create a recursive function that can count the amount of lowercase numbers in a word. This is what I have so far and im having difficulty implementing the low and high parameters that determine the range the function is checking.
def count_lowercase(s, low, high):
count = 0
if len(s) == 0:
return 0
elif s[low].islower():
count+=1
count_lowercase(s[low+1:high])
return count
You need to have the recursion step on the return, so they get called for every size until done.
This code does it, high defines the position of limit:
def count_lowercase(s, high=0):
count = 0
if len(s) == 0:
return 0
if high == 0:
high = len(s)
if s[0].islower():
count+=1
return count + count_lowercase(s[1:high+1])
You can use a function that checks if the first character is lowercase and recursively adds the number of lowercase characters in the rest of the string, or returns 0 if the string is empty:
def count_lowercase(s):
return len(s) and s[0].islower() + count_lowercase(s[1:])
Currently having difficulty figuring out this one. I know that I am very near but I cannot figure out where I am going wrong.
I would like the output to show a string, where an even number corresponds to '?--' and an odd number corresponds to '?-', and concatenate all of the strings together. Eg. star_wars_iteration(3) should return '?-?--?-'
However, mine does not add up, it only returns it once.
def star_wars_iteration(num_enemy_ships):
counter = 1
result = ''
while counter in range(1,num_enemy_ships + 1):
if counter % 2 == 0:
return '?--'
elif counter % 2 == 1:
return '?-'
result = result + counter
counter = counter + 1
return stops the function as soon as it is reached. Also you confuse while and for. What you want is:
def star_wars_iteration(num_enemy_ships):
result = ''
for counter in range(1,num_enemy_ships + 1):
if counter % 2 == 0:
result += '?--'
elif counter % 2 == 1:
result += '?-'
return result
Or if you want to use while then use while counter <= num_enemy_ships : (using in range(...) works too but is unnecessarily inefficient) and make sure the counter = counter + 1 line is inside the while block.
Note: more concise and pythonic:
def star_wars_iteration(num_enemy_ships):
return ''.join('?-' if counter % 2 else '?--' for counter in range(1,num_enemy_ships + 1))
Why don't you use the Pythonic iterators and range function for what they are meant to be you don’t need to increment starting and end values in the range:
def star_wars_iteration(num_enemy_ships):
return "".join('?-' if index % 2 else '?--' for index in range(num_enemy_ships))
How do I do a recursive function that tells me how many time an element exists in a list. As an example lets say I have the following list ['a','b','c','b','b','d']. How do I do a recursive function that takes 2 arguments. One being the list and the other the element. The function has to return the number of times the element is present in the list.
I tried the following but position gets restarted everytime we go back in the function:
def number_of_repetitions(liste, element):
position = 0
number_of_rep = 0
if position == len(liste)-1:
return number_of_rep
if liste[position] == element:
position +=1
return number_of_rep + number_of_repetitions(liste[position], element)
else:
position +=1
return number_of_rep + number_of_repetitions(liste[position], element)
print(number_of_repetitions(['a','b','c','b'],'b'))
def recursiveCount(lst,key):
if lst == []: #base case
return 0
if lst[0] == key:
return 1 + recursiveCount(lst[1:],key)
else:
return 0 + recursiveCount(lst[1:],key)
print recursiveCount(['a','b','a'],'a') #prints 2
Base case: empty list, there are no keys in the list
1st case: first element matches the key, count it (1) and recursive call on all but firsst element
2nd case: first element doesn't match, don't count it (0) and recursive call on all but first element
def element_count(input_list, ele, count=0):
if ele in input_list:
count = count + 1
input_list.remove(ele)
return element_count(input_list, ele, count)
else:
return count
input_list = ['a','b','c','b','b','d']
print "Count of 'b' in input list is :", element_count(input_list, 'b')
print "Count of 'a' in input list is :", element_count(input_list, 'a')
Gives count result as:
Count of 'b' in input list is : 3
Count of 'a' in input list is : 1
Taking advantage of the fact that True == 1 and False == 0:
def count(x, t):
if not x:
return 0
else:
return (x[0] == t) + count(x[1:], t)
Though I might honestly prefer the selected answer over this, as it's more explicit.
You don't need recursion for this.
print ['a','b','c','b','b','d'].count('b') #prints 3