Find count of number of pairs in the list - python

I have list of numbers:
[5, 4, 3, 4, 2, 1, 3, 5, 3, 5, 3, 5,]
A pair of numbers is the same 2 numbers. For example, 5 occurs 4 times, so we have 2 pairs of 5s. In the list above I can say I have 5 pairs. I want the output to count how many pairs of numbers are in the list.
I tried this, but got stuck.
list = [5,4,3,4,2,1,3,5]
print(list)
temp = 0
new_list = []
for index,x in enumerate(list):
elm_count = list.count(list[index])
if new_list:
for ind, y in enumerate(new_list):
if list[index] == new_list[ind]:
continue
if not elm_count % 2:
occ_count = elm_count/2
temp += occ_count
new_list.append(list[index])
continue

Simpler way to achieve this is using collections.Counter() with sum() as:
>>> my_list = [5, 4, 3, 4, 2, 1, 3, 5,3, 5, 3, 5,]
>>> sum(num//2 for num in Counter(my_list).values())
5
Here Counter() will generate a dict with number as key and count of occurrence of number in list as its value. Then I am iterating over its values and calculating the count of pairs for each number using generator expression, and doing summation on the count of all the pairs using sum().
You can refer below documents for more details:
collections.Counter() document
sum() document

To add, a solution without importing a package:
# Accepts a list of numbers as argument
def get_pairs(l):
already_counted = []
list_of_pairs = []
for i in l:
if not i in already_counted:
already_counted.append(i)
list_of_pairs.append(ar.count(i)//2)
return sum(list_of_pairs)
get_pairs([4,3,3,4,2,3,2,1,5]) # Run

Related

How to remove all repeating elements from a list in python?

I have a list like this:-
[1,2,3,4,3,5,3,6,7,8]
I want to remove the repeating element (here:- 3) completely from the list like this:-
[1,2,4,5,6,7,8]
How do I implement this in python such that not only the first occurrence of duplicate element is removed but all the duplicating values are removed
You can use Counter from collections to count the number of occurrences and select those elements which appear exactly once using a list comprehension:
from collections import Counter
a = [1,2,3,4,3,5,3,6,7,8]
[k for k, v in Counter(a).items() if v == 1]
(Counter basically returns a dictionary where elements are stored as keys and their counts are stored as values.)
This code should work
#Finding duplicate
def dup(x):
s = len(x)
duplicate = []
for i in range(s):
k = i + 1
for j in range(k, s):
if x[i] == x[j] and x[i] not in duplicate:
duplicate.append(x[i])
return duplicate
#begining
list1 = [1, 2, 3, 4, 3, 5, 3, 6, 7, 8]
#Finding duplicate
dup_list = (dup(list1))
#removing duplicates from the list
final_list = list(set(list1) - set(dup_list))
print(final_list)
A good and efficient way will be to use pandas
import pandas as pd
sample_list = [1,2,3,4,3,5,3,6,7,8]
unique_list = list(pd.Series(sample_list).drop_duplicates())
>> unique_list
>> [1, 2, 3, 4, 5, 6, 7, 8]
Use a set. To get rid of all repeating values use this:
a = [1,2,3,4,3,5,3,6,7,8]
print(a)
a = list(set(a))
print(a)
That will output
[1,2,3,4,3,5,3,6,7,8]
[1,2,4,5,6,7,8]

Count elements in a list without using Counter

Should be returning a dictionary in the following format:
key_count([1, 3, 2, 1, 5, 3, 5, 1, 4]) ⇒ {
1: 3,
2: 1,
3: 2,
4: 1,
5: 2,
}
I know the fastest way to do it is the following:
import collections
def key_count(l):
return collections.Counter(l)
However, I would like to do it without importing collections.Counter.
So far I have:
x = []
def key_count(l):
for i in l:
if i not in x:
x.append(i)
count = []
for i in l:
if i == i:
I approached the problem by trying to extract the two sides (keys and values) of the dictionary into separate lists and then use zip to create the dictionary. As you can see, I was able to extract the keys of the eventual dictionary but I cannot figure out how to add the number of occurrences for each number from the original list in a new list. I wanted to create an empty list count that will eventually be a list of numbers that denote how many times each number in the original list appeared. Any tips? Would appreciate not giving away the full answer as I am trying to solve this! Thanks in advance
Separating the keys and values is a lot of effort when you could just build the dict directly. Here's the algorithm. I'll leave the implementation up to you, though it sort of implements itself.
Make an empty dict
Iterate through the list
If the element is not in the dict, set the value to 1. Otherwise, add to the existing value.
See the implementation here:
https://stackoverflow.com/a/8041395/4518341
Classic reduce problem. Using a loop:
a = [1, 3, 2, 1, 5, 3, 5, 1, 4]
m = {}
for n in a:
if n in m: m[n] += 1
else: m[n] = 1
print(m)
Or explicit reduce:
from functools import reduce
a = [1, 3, 2, 1, 5, 3, 5, 1, 4]
def f(m, n):
if n in m: m[n] += 1
else: m[n] = 1
return m
m2 = reduce(f, a, {})
print(m2)
use a dictionary to pair keys and values and use your x[] to track the diferrent items founded.
import collections
def keycount(l):
return collections.Counter(l)
key_count=[1, 3, 2, 1, 5, 3, 5, 1, 4]
x = []
dictionary ={}
def Collection_count(l):
for i in l:
if i not in x:
x.append(i)
dictionary[i]=1
else:
dictionary[i]=dictionary[i]+1
Collection_count(key_count)
[print(key, value) for (key, value) in sorted(dictionary.items())]

Python arranging a list to include duplicates

I have a list in Python that is similar to:
x = [1,2,2,3,3,3,4,4]
Is there a way using pandas or some other list comprehension to make the list appear like this, similar to a queue system:
x = [1,2,3,4,2,3,4,3]
It is possible, by using cumcount
s=pd.Series(x)
s.index=s.groupby(s).cumcount()
s.sort_index()
Out[11]:
0 1
0 2
0 3
0 4
1 2
1 3
1 4
2 3
dtype: int64
If you split your list into one separate list for each value (groupby), you can then use the itertools recipe roundrobin to get this behavior:
x = ([1, 2, 2, 3, 3, 3, 4, 4])
roundrobin(*(g for _, g in groupby(x)))
If I'm understanding you correctly, you want to retain all duplicates, but then have the list arranged in an order where you create what are in essence separate lists of unique values, but they're all concatenated into a single list, in order.
I don't think this is possible in a listcomp, and nothing's occurring to me for getting it done easily/quickly in pandas.
But the straightforward algorithm is:
Create a different list for each set of unique values: For i in x: if x not in list1, add to list 1; else if not in list2, add to list2; else if not in list3, ad to list3; and so on. There's certainly a way to do this with recursion, if it's an unpredictable number of lists.
Evaluate the lists based on their values, to determine the order in which you want to have them listed in the final list. It's unclear from your post exactly what order you want them to be in. Querying by the value in the 0th position could be one way. Evaluating the entire lists as >= each other is another way.
Once you have that set of lists and their orders, it's straightforward to concatenate them in order, in the final list.
essentially what you want is pattern, this pattern is nothing but the order in which we found unique numbers while traversing the list x for eg: if x = [4,3,1,3,5] then pattern = 4 3 1 5 and this will now help us in filling x again such that output will be [4,3,1,5,3]
from collections import defaultdict
x = [1,2,2,3,3,3,4,4]
counts_dict = defaultdict(int)
for p in x:
counts_dict[p]+=1
i =0
while i < len(x):
for p,cnt in counts_dict.items():
if i < len(x):
if cnt > 0:
x[i] = p
counts_dict[p]-=1
i+=1
else:
continue
else:
# we have placed all the 'p'
break
print(x) # [1, 2, 3, 4, 2, 3, 4, 3]
note: python 3.6+ dict respects insertion order and I am assuming that you are using python3.6+ .
This is what I thought of doing at first but It fails in some cases..
'''
x = [3,7,7,7,4]
i = 1
while i < len(x):
if x[i] == x[i-1]:
x.append(x.pop(i))
i = max(1,i-1)
else:
i+=1
print(x) # [1, 2, 3, 4, 2, 3, 4, 3]
# x = [2,2,3,3,3,4,4]
# output [2, 3, 4, 2, 3, 4, 3]
# x = [3,7,1,7,4]
# output [3, 7, 1, 7, 4]
# x = [3,7,7,7,4]
# output time_out
'''

Sorting repeated elements

What I try to do is to write a function sort_repeated(L) which returns a sorted list of the repeated elements in the list L.
For example,
>>sort_repeated([1,2,3,2,1])
[1,2]
However, my code does not work properly. What did I do wrong in my code?
def f5(nums):
count = dict()
if not nums:
for num in nums:
if count[num]:
count[num] += 1
else:
count[num] = 1
return sorted([num for num in count if count[num]>1])
return []
if count[num]: will fail if the dictionary doesn't have the key already. Take a look at the various counter recipes on this site and use one instead.
Also, not nums is true if nums is an empty sequence, which means that the loop body will never be executed. Invert the condition.
Use a counter and check for values greater than 1
from collections import Counter
def sort_repeated(_list):
cntr = Counter(_list)
print sorted([x for x in cntr.keys() if cntr[x] > 1])
sort_repeated([7, 7, 1, 2, 3, 2, 1, 4, 3, 4, 6, 5])
>> [1, 2, 3, 4, 7]

Couting unique elements in python

I need a program which is couting unique elements in a list, but WITHOUT any built-in functions. I'm only allowed to use different lists and index of elements.
So if theres a list: [1, 6, 7, 2, 1, 6], solution must be: 4.
Starting with a second, empty list, use for to iterate over the items in your input list, check if they're in the new list, and if not then add them. Each time you do so, increment a counter by 1.
list1 = [1, 6, 7, 2, 1, 6]
list2 = []
Simple solution using set:
print len(set(list1))
Solution using list:
for i in list1:
if i not in list2:
list2.append(i)
print len(list2)
without len function:
for i in list1:
if i not in list2:
list2.append(i)
count = 0
for i in list2:
count += 1
print count

Categories

Resources