Find duplicate in list using built-in functions only [duplicate] - python

This question already has answers here:
check for duplicates in a python list
(7 answers)
Closed 4 years ago.
I am a TOTAL Noob so please be gentle!
I have written this code:
def sorted_has_duplicate(numbers):
numbers.sort()
duplicate = False
for num in range(len(numbers)-1):
if numbers[num] == numbers[num + 1]:
duplicate = True
break
return duplicate
The code runs fine and it does what it is supposed to do which is find the first duplicate value in a list if any and return True or False.
My question is how can I have the same function perform the same task if the list is not sorted (sorting is not allowed) and i can only use built in python functions?

Collect nums in a set as you iterate:
def has_duplicate(numbers):
seen = set()
for num in numbers:
if num in seen:
return True
seen.add(num)
return False
You can also shorten this down to:
def has_duplicate(numbers):
return len(numbers) != len(set(numbers))
This simply checks whether the list has as many elements as its set which by definition has no duplicates.
Note that both these set-based solutions run in linear time because of a set's O(1) contains-check. The naive brute force approach of searching for each element in the list remainder
def has_duplicate(numbers):
for i, num in enumerate(numbers):
if num in numbers[i+1:]:
return True
return False
is quadratic because of a list's O(N) contains-check.

Related

Why Recursive function return "None" [duplicate]

This question already has answers here:
Why does my recursive function return None?
(4 answers)
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 2 years ago.
Below code returns "None"
But, when I change (return sum) to (return
print(sum)) it returns right value.
Why does this problem occur?
def good(num,sum):
if num == 0:
return sum
sum = sum + num
num = num - 1
good(num,sum)
sum = 0
a = 3
k = good(a,sum)
print(k)
The return statement is missing!
Do this:
def good(num,sum):
if num == 0:
return sum
sum = sum + num
num = num - 1
return good(num, sum)
This is because the function is called but is not returning the new values recursively.
One of the best website that explains this in depth and clearly is realpython.com, have a look especially at: maintaining-state but I suggest you to have a look at the whole article.
For sake of completeness I quote a section where I think is related to the issue you encountered:
Behind the scenes, each recursive call adds a stack frame (containing its execution context) to the call stack until we reach the base case. Then, the stack begins to unwind as each call returns its results.
unwind: Basically it returns it backward.
When dealing with recursive functions, keep in mind that each recursive call has its own execution context.
Other Stack Overflow Related questions
recursive-function-returning-none-in-python
python-recursion-with-list-returns-none
i-expect-true-but-get-none

Python function which takes two arrays of integers and returns the number of integers that occur in both arrays [duplicate]

This question already has answers here:
Count duplicates between 2 lists
(5 answers)
Closed 2 years ago.
For example, if it takes the arrays [1,44,5,8,35] and [35,12,44,7,42,31] it will return 2,
because exactly two integers (44 and 35) occur in both the arrays.
The code should be library free
I have tried the following code:
A = [1,44,5,8,35]
B = [35,12,44,7,42,31]
def occurInBoth(A, B):
for i in range(len(A)):
for j in range(len(B)):
if A[i] == B[j]:
newA = [A[i]]
print(newA)
occurInBoth(A, B)
The result I get is:
[44]
[35]
And I'd like to get 2 as a result
Just editing this question because due to the nature of this module I cannot use libraries, import anything, use intersection etc. I have researched how to do this but I can only get answers that I cannot use for this task. Sorry if this has been asked before but haven't found anything for this specific task
You have the right idea with your for loops. What you want to do is create an accumulator value, and add 1 to it every time you find a match:
def occurInBoth(A, B):
total = 0
for i in range(len(A)):
for j in range(len(B)):
if A[i] == B[j]:
total += 1
return total
If both lists only contain unique numbers (no duplicates within their own lists), the below code is the simplest solution. We just need to compare the length of A+B combined lists with the length of the same integers put into a set (which removes all duplicates).
def occurInBoth(a, b):
return len(a+b) - len(set(a+b))
The easiest way to do this is:
def function_array_intersect(arr1,arr2):
return list(set(arr1).intersection(set(arr2)))
>>> function_array_intersect([1,2,3],[3,4,5])
Ans: [3]
Edit: to get the len, just add a len(list(set(arr1).intersection(set(arr2)))) in the return statement.

How to create a for loop, which returns True if the list's numbers are in order and otherwise False? [duplicate]

This question already has answers here:
Pythonic way to check if a list is sorted or not
(27 answers)
Check if a list contains incrementing elements starting from zero
(3 answers)
Closed 3 years ago.
I have attempted to write a function which loops over items in a list and returns True if the item is larger than the previous item in the list, and False if not, but it doesn't seem to work properly. Can anyone point me towards my error.
def inc_fun(x):
for i in range(len(x)):
for xi in x:
if x[i] > x[i-1]:
return True
else:
return False
inc_fun([1,2,3,7,9])
Returns: False
This should be true, if I run:
inc_fun([1,5,3,2,9])
This also returns false.
I appreciate any help :)
It seems to me that you actually want to check if the numbers in the list are in order from the smallest to the largest. You can achieve this easily with:
def inc_fun(x):
return x == sorted(x)
There really is very little point in using anything else when the lists are some hundred or thousand elements long, since this is the most readable and easy to understand way. But if you insist on being able to do this in linear time, you can use:
def inc_fun(x):
for i in range(len(x) - 1):
if x[i] > x[i + 1]:
return False
return True
Or the same in one line:
def inc_fun(x):
return all(x[i] <= x[i + 1] for i in range(len(x) - 1))
Your existing code has two big problems:
def inc_fun(x):
for i in range(len(x)):
# Using nested loops with a 1d list doesn't make much sense.
for xi in x:
# You return immediately after the first element,
# so you never check more than the first pair.
if x[i] > x[i-1]:
return True
else:
return False
For the first evaluation (i=0) of x[i-1], you get x[-1], which is equal to 9.
Your index i when at 0 is a problem.
Indeed when you do if x[i] > x[i-1] your are looking for x[0] and x[-1] and in python x[-1] is the last item of a list. So you are checking if 1 > 9 which is False
The other problem in your function is that you don't check the entire list but you are checking only once since you quit your function with return

Finding minimum value in a list recursively [duplicate]

This question already has answers here:
Recursive method to find the minimum number in a list of numbers
(6 answers)
Closed 5 years ago.
I'm trying to find the minimum value in a list recursively. Since I'm still new in adapting to the recursive method, I would like to seek some help regarding my line of code:
listA = [9,-2,6,1,80,9,-2]
def findMinimum(l):
if len(l) == 1:
return l
else:
minNumber = findMinimum(l-1)
min = listA[0]
for i in listA:
if listA[i]<listA[i+1]:
min = listA[i]
return min
findMinimum(listA)
I'll appreciate if anyone could help me out as I'm relatively new to recursion and my understanding is definitely up to standard.
The first part of your function is correct. But you should change the second part like this:
listA = [9,-2,6,1,80,9,-2]
def findMinimum(l):
if len(l) == 1:
return l[0]
else:
return min(l[0], findMinimum(l[1:]))
findMinimum(listA)
Remember, recursive functions comes to make our codes simpler and easier.
The structure of your code is about right, but it has some mistakes. First, you should not be using listA inside of your function; listA is passed as an argument from the outside, and from within the function you should only refer to l. In the non-recursive case (where len(l) == 1), you should return l[0] (the minimum of a list with one element is that one element). Then, it is correct to call findMinimum inside your function again (that's the recursive call, as you know); however, what you probably want is to call it with the all the list l except the first element, that is, l[1:]. Then, you should compare the result minNumber to the first element of l; the idea is that you pick the smallest of l[0] and the minimum in l[1:]. Then you return the one you have chosen.
Additionally, you may want to consider the case when you get an empty list and throw an error; if you don't, you may get into an infinite recursion!
So a possible solution could be something like this:
listA = [9,-2,6,1,80,9,-2]
def findMinimum(l):
if len(l) == 0:
raise ValueError('Cannot find the minimum of an empty list.')
elif len(l) == 1:
return l[0]
else:
minNumber = findMinimum(l[1:])
min = l[0]
if minNumber < min:
min = minNumber
return min
findMinimum(listA)

Check whether an element occurs in a list using recursion [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
def check(x,num,i):
for n in range(len(x)):
if x[i] == num:
return True
else:
return(check(x,num,i+1))
return False
def User(x,num):
return(check(x,num,0))
User([2,6,1,9,7,3],5,0)
this should out put false since 5 is not in the list
checks whether an element occurs in a list recursively
so for example:
Input: a list L read from the keyboard, for example L = [2,6,1,9,7,3]
an element e, for example e = 9
but for some reason, i get an error when the number is not in the list
The beauty (and purpose) of recursion is that you do not need the loop:
def check(x, num, i):
if not x[i:]: # index past length
return False
if x[i] == num:
return True
return(check(x, num, i+1))
You can also do without the index parameter:
def check(x, num):
if not x:
return False
return x[0] == num or check(x[1:], num)
I don't exactly understand what you're doing, but this is a bizarre combination of recursion and iteration. If you're going to use recursion, it's worthwhile, at least for a basic recursive problem like this, to avoid iteration. Try something like this
def check(x, num, i = 0):
if i >= len(x):
return False
elif x[i] == num:
return True
else:
return check(x, num, i + 1)
This solution will work perfectly fine and is tail recursive so it will work quickly and optimally.
The way this works is it checks if the index, i, is out of bounds. If so, then it returns False. If it is in bounds, it checks if x[i] is equal to the number. If so, it returns True. If it is not, it returns check with the index increased and thus the recursion works.
First of all, your for loop doesn't make any sense. You never use that n and never go into the loop a second time, as you always return something in the first iteration. The return statement after the for loop is also unreachable, so your code could as well be
def check(x,num,i):
if x[i] == num:
return True
else:
return(check(x,num,i+1))
Then the actual issue is, that if you have a list with 5 elements for example, which does not contain the element searched for, you ask what the 6th is, although there is no 6th element, thus the error. You'd have to check whether the list contains 6 elements. So you check whether it has more than 5, return false if it does and continue if it doesn't. (Alternatively you could also check this at the start of the whole function)
def check(x,num,i):
if x[i] == num:
return True
else:
if len(num)>i:
return False
else:
return(check(x,num,i+1))
What you've done then is nothing but a overcomlicated, recursive for-Loop. You just increase i and compare, until you find the element or i is bigger than the list length. So this is equivalent to
def check(x,num):
for i in range(len(num)):
if x[i]==num:
return True
return False
It is very important that the return False is AFTER the for-Loop, as you only return, if you didn't find the element, even after iterating over the WHOLE list.
Also you can avoid indices. With a for-Loop you can directly iterate over the elements in a list:
def check(x,num):
for elem in num:
if elem==num:
return True
return False
This makes the variable elem become every element in you list, one after another.

Categories

Resources