The function below returns the index within the list list_of_items of the first item that is equal to search_item. If no such items exist the function returns -1.
With a while loop rather than a for loop and not using any break statements nor index method of a list. How can I reduce my function below so that it only contains a single return statement?
With the restriction to a while loop, and not using any break statements (making this seem a lot like a homework question), your best bet is to create a second condition that controls the execution of the loop. For example:
def my_index(list_of_items, search_item):
i = 0
done = False
return_value = '-1' # I suspect you meant this to be an int, not str
while i < len(list_of_items) and not done:
if list_of_items[i] == search_item:
done = True
return_value = i
else:
i += 1
return return_value
Is this considered breaking?
def my_index(list_of_items, search_item):
res = -1
i = 0
while i < len(list_of_items):
if list_of_items[i] == search_item:
res = i
i = len(list_of_items)
else:
i += 1
return res
def my_index(list_of_items, search_item):
ret = -2
i = 0
while i < len(list_of_items):
if list_of_items[i] == search_item:
ret = i
elif i == (len(list_of_items) - 1):
ret = -1
if ret != -2:
return ret
i += 1
list_of_items = [3, 7, 2, 9, 11, 19]
print(my_index(list_of_items, 3))
Related
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 the problem is asking me to return the sum of even or odd elements in a list given the condition odd or even. So if the condition is odd, I have to return a list of all odd numbers. If the list is blank/the values do not match the condition, then return 0.
This is what I have so far:
l = [1,2,3,4,5,6]
def conditionalSum(value, condition):
s = 0
if condition == "even":
for i in l:
if i % 2 == 0:
s += i
elif condition == "odd":
for i in l:
if i % 2 !=0:
s = s+ i
else:
return 0
When I try to run this, nothing comes up - not even an error! Any help is appreciated
your code can be modified to be more pythonic using a built-in sum function.
l = [1, 2, 3, 4, 5, 6]
def conditionalSum(value, condition):
if condition == "even":
return sum(i for i in l if i % 2 == 0)
elif condition == "odd":
return sum(i for i in l if i % 2 == 1)
else:
return 0
print(conditionalSum(value, "even"))
Output:
12
btw you have an unused variable value in your function conditionalSum
you need to call the fonction: conditionalSum(l, "even") for instance
you don't return any value for the 2 conditions "even" and "odd". Corrected code:
l = [1,2,3,4,5,6]
def conditionalSum(value, condition):
s = 0
if condition == "even":
for i in value:
if i % 2 == 0:
s += i
elif condition == "odd":
for i in value:
if i % 2 !=0:
s += i
return s
print(conditionalSum(l,"even"))
print(conditionalSum(l,"odd"))
In this function, I want to return a value when the if statement is executed.
Since Python always returns something, it returns None.
def Persistence(number, counter):
numArr = [int(i) for i in str(number)]
result = 1
data = None
for j in numArr:
result *= j
if len(str(number)) == 1:
data = str(f'Done. {counter} steps taken')
print(data)
# return data
else:
counter = counter + 1
Persistence(result, counter)
# return data
print(Persistence(333,0))
Maybe I put the return keyword in the wrong place (I checked by putting it in two different places, marked as a comment) or something else, but I couldn't figure it out.
Please help me out. Also, if there is another way to count the recursion steps besides my technique, please let me know.
Maybe try this :
def Persistence(number, counter):
numArr = [int(i) for i in str(number)]
result = 1
for j in numArr:
result *= j
if len(str(number)) == 1:
return str(f'Done. {counter} steps taken')
counter = counter + 1
return Persistence(result, counter)
print(Persistence(333,0))
Hope it helps
The issue is that you're not setting the value from the else call to persistence to anything. The following code return the data value for me:
def Persistence(number, counter):
numArr = [int(i) for i in str(number)]
result = 1
data = None
for j in numArr:
result *= j
if len(str(number)) == 1:
data = str(f'Done. {counter} steps taken')
print(data)
return data
else:
counter = counter + 1
data = Persistence(result, counter)
return data
x = Persistence(333, 0)
Then if we print x:
print(x)
# Done. 3 steps taken
Your logic to count the recursion steps is basically correct, you just need to place the return statements for both the:
1)Base case
2)The recursive call itself
The following modification to your code will do the trick of what you are asking:
def Persistence(number, counter):
numArr = [int(i) for i in str(number)]
result = 1
data = None
for j in numArr:
result *= j
if len(str(number)) == 1:
data = str(counter)
return data
else:
counter = counter + 1
return Persistence(result, counter)
print(Persistence(333,0))
The above code will return the output of:
3
Please note that the reason you were getting "None" as the output in your original code is because you were not making a return at the actual recursive call itself: **return** Persistence(result, counter)
So when you ran print(Persistence(333,0)) it was returning nothing resulting in the None.
This question is better to learn about recursion than you may think. But we won't muddy the waters by mixing recursion (functional style) with statements and side effects (imperative style).
It looks like you're trying to calculate multiplicative root and persistence. Instead of putting all concerns of the computation into a single function, break it down into sensible parts -
def digits (n = 0):
if n < 10:
return [ n ]
else:
return digits (n // 10) + [ n % 10 ]
def product (n = 0, *more):
if not more:
return n
else:
return n * product (*more)
def mult_root (n = 0):
if n < 10:
return [ n ]
else:
return [ n ] + mult_root (product (*digits (n)))
def mult_persistence (n = 0):
return len (mult_root (n)) - 1
print (mult_persistence (333))
# 3
print (mult_root (333))
# [ 333, 27, 14, 4 ]
So I have been having this issue with a simple python script I'm working on for an assignment. I am to make a small script simulating a lottery, and have written this code:
import random
def drawNumbers(nlist, n):
drawnlist = []
i = 0
while i < n:
if i == 0:
drawnlist.append(nlist[random.randint(0,33)])
i+=1
else:
r = random.randint(0,33)
dup = False
for x in drawnlist:
if x == r:
dup = True
if dup == False:
drawnlist.append(nlist[r])
i+=1
return drawnlist
def compList(drawlist, guesslist):
count = 0
for j in drawlist:
for h in guesslist:
if j == h:
count +=1
return count
def winnings(right, altright):
altcorrect = False
if altright > 0:
altcorrect = True
if right == 7:
return 2749455
elif right == 6:
if altcorrect:
return 102110
else:
return 3385
elif right == 5:
return 95
elif right == 4:
if altcorrect:
return 45
else:
return 0
a=0
tot = 0
while a <100:
numbers = []
i = 1
while i <= 34:
numbers.append(i)
i+=1
myGuess = []
i = 0
while i <7:
if i == 0:
myGuess.append(random.randint(1,34))
i+=1
else:
r = random.randint(1,34)
dup = False
for x in myGuess:
if x == r:
dup = True
if dup == False:
myGuess.append(r)
i+=1
tot += winnings(compList(drawNumbers(numbers,7),myGuess),compList(drawNumbers(numbers,3),myGuess))
a+=1
print(tot)
And it seems to be working fine for one iteration, however, when I increase a like now with a value of 100, I get an error saying that I cannot sum an "int" object and a "None" objects. When I tinkered with the code and printed "winnings" instead of the summed total for each iteration, it looks like the function sometimes returns "None" instead of a number. I can however not seem to recreate that with a smaller amount of iterations, so my question: Is this code related, or might it be that by calling the functions "too fast" it does not create a number? I know this question might seem odd, but I am new to programming as a whole and python itself, and I have no clue how to debug this.
The winnings function can return None as there is no else to the inner if. In this case, it does not trigger the final else and returns None by default. To fix it, add an else to the if, or just remove the final else in winnings:
def winnings(right, altright):
altcorrect = False
# ...
elif right == 4:
if altcorrect:
return 45
# maybe add an else here?
# or if you get to this point, _always_ return 0
return 0
Your winnings function sometimes returns None. It's because it's not catching some cases. Python returns None if it reaches the end of a function without any other returns being hit.
Specifically, if right is 4 and altright is 0, none of the if cases will get caught and the function returns None.
I have a while loop which calls the function mainrt() on each iteration.
if __name__ == "__main__":
inp = sys.stdin.read()
inpList = inp.split('\n')
inpList.pop()
for n in inpList:
i = 0
p = 0
n = int (n)
while True:
i += 1
p = n*i
if n == 0:
print "INSOMNIA"
break
else:
res = True
res = mainrt(p)
if res == False:
print p
break
And the mainrt()
def mainrt(n):
#print n
while True:
rem = n % 10
if rem in diMon:
pass
else:
diMon.insert(rem,rem)
if len(diMon) == 10:
return False
break
n = n/10
if n == 0:
return True
break
else:
continue
The problem is as i take input from stdin.read() the first line of the input processed properly by the function, but the second line of the input get printed as it is. It is not being processed by the function
example
INPUT
3
5
OUTPUT SHOLD BE
30
90
But instead I get
30
5
Why the function not processing the input the second time???
There is no run time error so far.
In your mainrt function I do not see that you declare diMon list, so it looks like it is a global variable and you do not clean that list. That mean your mainrt return False at the first check of if len(diMon) == 10: for the second input. You should declare diMon at the beginning od mainrt function or clear it at the end of while loop body.
EDIT:
Now I checked your code one more time and I suggest you to declare diMon at the beginning of for loop
for n in inpList:
diMon = []
i = 0
p = 0
n = int (n)