Find position of duplicate elements in list - python

Basically I want to find and print the positions of all the duplicate elements. Here is my code:
numbers = [7,1,3,6,4,2,5,9,8,10]
n = int(input("Enter a number from 1 to 10 to search for the number's position: "))
def findNum():
count = 0
while numbers[count] != n:
count += 1
numPos = count + 1
print(numPos)
if n in numbers:
print("Calculating position... (takes 9 years so wait)")
findNum()
else:
print("Number not found, next time enter a number from 1 to 10!")
For example I add an extra 7 to numbers:
numbers = [7,1,3,6,4,2,5,9,8,10,7]
Then I want to return the 1st 7's position and also the other 7's position. How to do it?

To get all duplicates use a dictionary with the keys as the numbers in the list and the values the positions, to get the positions use enumerate:
from collections import defaultdict
numbers = [7, 1, 3, 6, 4, 2, 5, 9, 8, 10, 7]
duplicates = defaultdict(list)
# iterate over positions and numbers simultaneously
for i, number in enumerate(numbers):
# accumulate positions to the same number
duplicates[number].append(i)
result = {key: value for key, value in duplicates.items() if len(value) > 1}
print(result)
Output
{7: [0, 10]}
As you can see from the output it returns that 7 appears in position 0 an 10. The overall complexity of this approach is O(n).
The loop:
# iterate over positions and numbers simultaneously
for i, number in enumerate(numbers):
# accumulate positions to the same number
duplicates[number].append(i)
group the different positions (i in the code) by the same number. Using a defaultdict.
The expression:
result = {key: value for key, value in duplicates.items() if len(value) > 1}
is a dictionary comprehension, see some more info here.

numbers = [7,1,7,6,4,2,5,9,8,10,7]
m=[]
for i in range(len(numbers)):
for j in range(i+1,len(numbers),1):
if(numbers[i]==numbers[j]):
m.append(i)
m.append(j)
l=list(set(m))
for i in range(len(l)):
print("First Occurence at position:{}".format(l[i]))

Related

If element is repeated in list remove element from that list [duplicate]

This question already has answers here:
Removing duplicates in lists
(56 answers)
Closed 1 year ago.
my_list = [1,2,3,4,2,3]
so my desired list should be like
new_list = [1,4]
duplicate values should be removed along with the original ones
Attempt -
output = []
for x in my_list:
if x not in output:
output.append(x)
print(output)
One option is to use collections.Counter, and then filter out items of multiple appearances:
[v for v, c in collections.Counter([1, 2, 3, 4, 2, 3]).items() if c == 1]
The Counter will create a dictionary with the items: Counter({1: 1, 2: 2, 3: 2, 4: 1}).
You can use the .count() method of the lists, along with a list comprehension.
For example:
my_list = [1,2,3,4,2,3]
new_list = [x for x in my_list if l.count(x) == 1]
print(new_list) # Prints [1,4]
all approaches are good
I want to add a different approach
def duplicate_deleter(list_object):
set_obj=set(list_object)
result=[]
for i in set_obj:
if list_object.count(i)==1:
result.append(i)
return result
Without collections you can use a dictionary to count the frequency of the items in the list then keep only those with low enough frequency. This example runs in O(n+m) where n is the number of elements in the original list and m is the number of unique elements.
lst = [1,2,2,3,4,5,4]
freq = dict()
for el in lst:
if el in freq:
freq[el] += 1
else:
freq[el] = 1
print([el for el, f in freq.items() if f < 2])
You can create a program to pop the list x number of times for each duplicate element, where x is equals to the count of a duplicate element in the list.
my_list = [1,2,3,4,2,3]
#Sort the list so the index matches the count arrays index
my_list.sort()
#Create the count array using set to count each unique element
count = [my_list.count(x) for x in set(my_list)]
#Create another count to cycle through the count array
count1 = 0
#Create a popped variable to keep record of how many times the list has been altered
popped = 0
while (count1 < len(count)):
if count[count1] > 1:
#Create a variable to pop r number of times depending on the count
r = 0
while (r < count[count1]):
#If the list has already been popped, the index to be examined has to be the previous one.
#For example, after the 2's have been popped we want it to check the first 3
#which is now in the count1-1 index.
my_list.pop((count1 - popped))
r = r+1
popped = popped + 1
count1 += 1
print(my_list)
else:
count1 += 1

How to add elements in a list if they are in increasing order in a list?

I am practicing python questions and came across this question where I have to add elements in a list if they are in increasing order and store them in a list.
For example:
my_list = [2,223,6,4,10,12,15]
From 2 to 223, the list is increasing and then from 223 to 6, it is decreasing. Thus, the sum is 2+223=225.
From 223 to 6, 6 to 4 the list is decreasing and from 4 to 10, 10 to 12, 12 to 15 it is increasing, so sum is 4+10+12+15=41.
So, my sum_list will be [225,41].
The code I tried:
list1 = [2,223,6,4,10,12,15]
current_el = list1[0]
suml=list()
sum1=current_el
for i in list1[list1.index(current_el)+1:]:
while current_el < i:
print(i)
sum1=sum1+i
current_el = list1[list1.index(current_el)+1]
print(current_el)
suml.append(sum1)
print(suml)
This is way simpler:
numbers = [2, 223, 6, 4, 10, 12, 15]
accumulated = []
for i in range(1, len(numbers)):
if numbers[i] > numbers[i-1]:
if i == 1 or numbers[i-1] <= numbers[i-2]:
accumulated.append(numbers[i-1])
accumulated[-1] += numbers[i]
With if numbers[i] > numbers[i-1] we check if a number is greater than the previous (increasing) and with accumulated[-1] += numbers[i] we add that number to the last accumulated value. Now we are only missing the logic to create a new element in the accumulated list, and this is when we find a number that is greater than the previous but the previous iteration didn't pass this condition or if there are no previous pair that we can check.
Another different solution more similar to the one you were trying would be doing this in two steps. The first step would create a list of lists with numbers grouped by ascending groups. Then you discard those groups of a single member (you are not considering 6 as an ascending group) and then you add the groups together.
numbers = [2, 223, 6, 4, 10, 12, 15]
groups = [[2]]
for number in numbers[1:]:
if number > groups[-1][-1]:
groups[-1].append(number)
else:
groups.append([number])
accumulated = []
for group in groups:
if len(group) == 1:
continue
accumulated.append(sum(group))

How to return the longest subsequence formed by consecutive numbers in a Python list?

I am able to calculate the length of the longest ascending subsequence formed by consecutive numbers in a list, or the largest sum of any subsequence. However, I am a bit struggling to print out the longest subsequence with consecutive numbers (e.g: 8,9,10,11,12). How can I do that? Should I create an empty list and override the values every time the num value is being checked in the new_list?
Thanks in advance,
lanuit72
def longest_largest_seq(list):
list = [5,6,3,8,3,4,9,8,10,12,11,99,98]
largest = 0
sum = 0
new_list = set(list) #using set to get unique value from the list
max_count = 0
count = 0
for num in list:
if num - 1 not in new_list:
sum = 0
count = 0
while num in new_list:
sum += num
count += 1
num += 1
if sum > largest:
largest = sum
if count > max_count:
max_count = count
return largest, max_count
print(f'Largest consecutive sum and longest consecutive subsequence', longest_largest_seq(list))
Something like this?
from more_itertools import consecutive_groups
a_list = [5,6,3,8,3,4,9,8,10,12,11,99,98]
sorted_list = sorted(a_list)
grouped = [list(i) for i in consecutive_groups(sorted_list)]
for i in grouped:
print(i)
print('\n', max(grouped, key=len), sep='')
[3]
[3, 4, 5, 6]
[8]
[8, 9, 10, 11, 12]
[98, 99]
[8, 9, 10, 11, 12]
I think this is what you want?
import copy
seq = sorted([5,6,3,8,3,4,9,8,10,12,11,99,98])
sub_seq1 = []
sub_seq2 = []
for index, num in enumerate(seq):
if index < len(seq) - 1:
if num + 1 == seq[index + 1]:
sub_seq2.append(num)
else:
sub_seq2.append(num)
if len(sub_seq2) > len(sub_seq1):
sub_seq1 = copy.deepcopy(sub_seq2)
sub_seq2.clear()
print(sub_seq1)

Count repetitions of the same number going one after another in a list of numbers

I have a list of numbers of the form [1,2,2,2,3,2,2,2,2] and I need to find the maximum frequency of duplicates going one after the other. In the example above we have overall 7 '2's but the correct answer is 4 because 4 is the sequence of numbers with the greatest length. In the case of [1,2,2,2,2,2,1,2,2], we have correct answer as 5 even though we have 7 duplicates of 2.
I tried to use the following code for list for finding duplicates of each number going one after the other:
list1 = [1,2,2,2,3,2,2,2,2]
for number in set(list1):
count = 1
list1 = [1,2,2,2,3,2,2,2,2]
for idx, i in enumerate(list1):
if i == number and list1[idx-1] == number:
count += 1
else:
count == 0
print(number, count)
But it does not correctly work as it also includes some of the duplicates from the previous "set of duplicates".
The output was:
1 1
2 6
3 1
Another possibility is:
from itertools import groupby
from operator import itemgetter
ll = [[1,2,2,2,3,2,2,2,2], [1,2,2,2,2,2,1,2,2]]
for l in ll:
counts = [(i, len(list(c))) for i, c in groupby(l)]
indices = list(map(itemgetter(1), counts))
idx = indices.index(max(indices))
print(counts[idx])
Where you can get the element with the number of repetitions, depended on the needs.
Use itertools.groupby with max
Ex:
from itertools import groupby
data = [[1,2,2,2,3,2,2,2,2], [1,2,2,2,2,2,1,2,2]]
for i in data:
print(max((list(v) for _, v in groupby(i)), key=len))
Output:
[2, 2, 2, 2]
[2, 2, 2, 2, 2]
Sticking to your way of solving it:
final_count = []
count = 0
list1 = [1,2,2,2,3,2,2,2,2]
for idx, i in enumerate(list1):
if i == 2:
count += 1
if idx == len(list1) - 1: final_count.append(count)
else:
final_count.append(count)
count = 0
result = max(final_count)
print(result)

Unique sums greater than a number

So I'm trying to write a code that takes a list of numbers between 1 and 10 and finds sums that are greater or equal than 10 and then remove those numbers from the list. Here's the twist: first you need to check if there is any 10 in the list, the any couple of numbers that sum to 10, then any 3 numbers and so on until 5. Also, the lower the numbers summed the better. So you need to get rid of most numbers when summing couples. So far I managed to do the couples:
n = input("How many numbers in the list? \n")
throw = []
for i in range(int(n)):
throw.append(random.randint(1, 10))
throw.sort()
increments = 0
print(throw)
increments += throw.count(10)
throw = list(filter(lambda i: i != 10, throw))
high = len(throw)-1
low = 0
acceptable_couples = []
get_rid = []
while low < high:
sums = throw[high] + throw[low]
if sums >= 10:
increments += 1
get_rid.append(throw[high])
get_rid.append(throw[low])
acceptable_couples.append((throw[high], throw[low]))
high -= 1
low += 1
else:
low += 1
for i in get_rid:
throw.remove(i)
I also did the pairs of 3 and was thinking to apply the same method for 4, and 5:
while len(throw) >= 3:
z = 0
x = list(itertools.combinations(throw, 3))
for couple in x:
if sum(couple) >= 10:
z += 1
i = list(couple)
increments += 1
for j in couple:
throw.remove(j)
break
else:
continue
if z == 0:
break
I was hoping to find a less messy way to do it. This works, but for large number of numbers it seems a lot of useless computation.
Any ideas?
In that case perhaps this would be a solution. In pseudo code:
Read list of numbers and sort from high to low
remove all numbers 10 from the list and add these as a solution
Loop until list is empty
take the largest number in the list (which is the first number as list is sorted) and remove it from the list
Check if by adding the smallest number we can get a sum greater or equal to 10 if not go to a bigger number until we complete the loop. Break loop if a solution is found, add to solutions and remove the element from the list that solved it.
if solved break and repeat the outer while loop with next biggest number in the list. If not solved then add the next biggest number to the sum and remove it from the list and check if we can find a solution adding smaller numbers running the for loop again
Code
import random
n = int(input("How many numbers in the list? \n"))
throw = [random.randint(1, 6) for _ in range(n)]
print(throw)
throw.sort(reverse=True)
print(throw)
list_of_solved_sets = []
# remove all numbers 10 from the list and add a solution
while throw and throw[0] == 10:
list_of_solved_sets.append([throw[0]])
del throw[0]
while throw:
# take the largest number in the set (which is the first number
# as list is sorted) and remove it from the list
solved_set = [throw[0]]
_sum = throw[0]
del throw[0]
while throw:
solved = False
# Check if by adding the smallest number we can get
# a sum greater or equal to 10 if not go to a bigger number
# until we complete the loop. Break loop if a solution is found, add
# to solutions and remove element from the list that solved it
for j in range(len(throw) - 1, -1, -1):
if _sum + throw[j] >= 10:
solved_set.append(throw[j])
del throw[j]
list_of_solved_sets.append(solved_set)
solved = True
break
# if solved break and repeat the outer while loop with next biggest number
# in the list. If not solved then add the next biggest number to the sum and
# check if we can find a solution adding smaller numbers running the for
#loop again
if solved:
break
else:
_sum += throw[0]
solved_set.append(throw[0])
del throw[0]
print('List of solved sets:')
for i, solved_set in enumerate(list_of_solved_sets):
print(f' {i+1}: {solved_set}')
Result example:
How many numbers in the list?
10
[3, 2, 5, 1, 6, 3, 4, 3, 2, 1]
[6, 5, 4, 3, 3, 3, 2, 2, 1, 1]
List of solved sets:
1: [6, 4]
2: [5, 3, 2]
3: [3, 3, 2, 1, 1]
Not sure if I understand your question correctly. My interpretation is that you have a set of numbers between 1 and 10 and you need to find the longest sub sets of numbers from this set that sum up to 10 or greater and then remove these numbers from the original set until you can not find any more sets with more than one number.
If this is the correct interpretation than the following should work:
import random
n = int(input("How many numbers in the list? \n"))
throw = [random.randint(1, 10) for _ in range(n)]
print(throw)
throw.sort()
list_of_solved_sets = []
sets_found = True
while sets_found:
_sum = 0
solved_set = []
solved_indexes = []
for index, element in enumerate(throw):
_sum += element
solved_set.append(element)
solved_indexes.append(index)
if _sum >= 10:
break
if len(solved_set) <= 1:
sets_found = False
else:
list_of_solved_sets.append(solved_set)
for index in reversed(solved_indexes):
del throw[index]
print('List of solved sets:')
for i, solved_set in enumerate(list_of_solved_sets):
print(f' {i+1}: {solved_set}')
Note you need to remove the indexes from the list throw in reversed order!

Categories

Resources