Find most common element - python

How can I print the most common element of a list without importing a library?
l=[1,2,3,4,4,4]
So I want the output to be 4.

You can get the unique values first:
l = [1, 2, 3, 4, 4, 4]
s = set(l)
then you can create list of (occurrences, value) tuples
freq = [(l.count(i), i) for i in s] # [(1, 1), (1, 2), (1, 3), (3, 4)]
get the "biggest" element (biggest number of occurrences, the biggest value if there are more than one with the same number of occurrences):
result = max(freq) # (3, 4)
and print the value:
print(result[1]) # 4
or as a "one-liner" way:
l = [1, 2, 3, 4, 4, 4]
print(max((l.count(i), i) for i in set(l))[1]) # 4

lst=[1,2,2,2,3,3,4,4,5,6]
from collections import Counter
Counter(lst).most_common(1)[0]
Counter(lst) returns a dict of element-occurence pairs. most_common(n) returns the n most common elements from the dict, along with the number of occurences.

Related

Finding all combinations of a list of numbers without the pair being the same in python

I would like to find all combinations of my list of numbers without the pair being the same. The code I've written below gives me all combinations. So, I also get [1, 1], [2, 2] and [3, 3], which I'd like to remove.
nr_list = [1, 2, 3]
combinations = []
for a in nr_list:
for b in nr_list:
pair = [a, b]
combinations.append(pair)
print(combinations)
from itertools import permutations
nr_list = [1, 2, 3]
print(list(permutations(nr_list, 2)))
# [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
Similar question: link
Just don't append the pair to the combinations if the items in pair are equal ie if pair[0] != pair[1]:
Try this code
nr_list = [1, 2, 3]
combinations = []
for a in nr_list:
for b in nr_list:
if(a!=b):
pair = [a, b]
combinations.append(pair)
print(combinations)

Python. How to conveniently count the frequence of lists in a collection of lists

I have a list of list.
e.g. list_a = [[1,2,3], [2,3], [4,3,2], [2,3]]
I want to count them like
[1,2,3]: 1
[2,3]: 2
[4,3,2]: 1
There is a library Counter in collections but not for unhashable elements like list. Currently, I just try to use other indirect ways for example transfer the list [1,2,3] into a string "1_2_3" to do that. Is there any other way can enable the count on the list directly?
Not the prettiest way to do it, but this works:
list_a = [[1,2,3], [2,3], [4,3,2], [2,3]]
counts = {}
for x in list_a:
counts.setdefault(tuple(x), list()).append(1)
for a, b in counts.items():
counts[a] = sum(b)
print(counts)
{(2, 3): 2, (4, 3, 2): 1, (1, 2, 3): 1}
A possible approach to do this job is using a dict.
Create a empty dict
Iterate over the list using a for loop.
For each element (iteration), check if the dict contains it.
If it doesn't, save it in the dict as a key. The value will be the occurrence counter.
If it does, just increment its value.
Possible implementation:
occurrence_dict = {}
for list in list_a:
if (occurrence_dict.get(str(list), False)):
occurence_dict[str(list)] += 1
else:
ocorrence_dict[str(list)] = 1
print(occurence_dict)
You can achieve it easily, by using tuple instead of list
c = Counter(tuple(item) for item in list_a)
# or
c = Counter(map(tuple, list_a))
# Counter({(2, 3): 2, (1, 2, 3): 1, (4, 3, 2): 1})
# exactly what you expected
(1, 2, 3) 1
(2, 3) 2
(4, 3, 2) 1
Way 1
Through the indexes of repeatable lists
list_a = [[1,2,3], [2,3], [4,3,2], [2,3], [1,2,3]] # just add some data
# step 1
dd = {i:v for i, v in enumerate(list_a)}
print(dd)
Out[1]:
{0: [1, 2, 3], 1: [2, 3], 2: [4, 3, 2], 3: [2, 3], 4: [1, 2, 3]}
# step 2
tpl = [tuple(x for x,y in dd.items() if y == b) for a,b in dd.items()]
print(tpl)
Out[2]:
[(0, 4), (1, 3), (2,), (1, 3), (0, 4)] # here is the tuple of indexes of matching lists
# step 3
result = {tuple(list_a[a[0]]):len(a) for a in set(tpl)}
print(result)
Out[3]:
{(4, 3, 2): 1, (2, 3): 2, (1, 2, 3): 2}
Way 2
Through converting nested lists to tuples
{i:[tuple(a) for a in list_a].count(i) for i in [tuple(a) for a in list_a]}
Out[1]:
{(1, 2, 3): 2, (2, 3): 2, (4, 3, 2): 1}

How to count elements inside list with specific condition

I am making combination of six number is seems easy but i need output of specific combination
i think i need to use count function and loop?????
from itertools import combinations
comb = combinations([1, 2, 3, 4, 5, 6], 3)
for n in list(comb):
print (n)
Actual result give me 20 combination, but i need solution of code gives me only combination n where n(n1,n2,n3) n1+n2=n3,
so in my case it will be
(1,2,3) (1,3,4) (1,4,5) (1,5,6) (2,3,5) (2,4,6)
i need solution of code gives me only combination n where n(n1,n2,n3) n1+n2=n3
Add that as an if statement inside the for loop:
for n in comb:
if n[0] + n[1] == n[2]:
print (n)
Try this oneliner:
from itertools import combinations as combs
print(list(filter(lambda c: c[0]+c[1]==c[2], combs(range(1,7), 3))))
Or if your want to print one combination at a time you can do:
from itertools import combinations as combs
for comb in filter(lambda c: c[0]+c[1]==c[2], combs(range(1,7), 3)):
print(comb)
Another solution:
result = [(x,y,z) for (x,y,z) in combinations([1, 2, 3, 4, 5, 6], 3) if x+y==z]
print(result)
[(1, 2, 3), (1, 3, 4), (1, 4, 5), (1, 5, 6), (2, 3, 5), (2, 4, 6)]

Indices of intersection of lists

Given two lists of equal length:
_list = [1, 4, 8, 7, 3, 15, 5, 0, 6]
_list2 = [7, 4, 0, 1, 5, 5, 7, 2, 2]
How do I try getting an output like this:
output = [(0,3), (1,1), (3,0), (6,4), (6,5), (7,2)]
Here the intersection of two lists are obtained and the common elements' indices are arranged in the list:
output = list of (index of an element in _list, where it appears in _list2)
Trying intersection with sets is not an option since the set removes the repeating elements.
Basic-Intermediate: As a generator:
def find_matching_indices(a, b):
for i, x in enumerate(a):
for j, y in enumerate(b):
if x == y:
yield i, j
list(find_matching_indices(list1_, list2_))
# [(0, 3), (1, 1), (3, 0), (3, 6), (6, 4), (6, 5), (7, 2)]
Basic-Intermediate: As a list comprehension:
[(i, j) for i, x in enumerate(list1_) for j, y in enumerate(list2_) if x == y]
# [(0, 3), (1, 1), (3, 0), (3, 6), (6, 4), (6, 5), (7, 2)]
These solutions involve two loops.
Intermediate-Advanced: For fun, a dictionary is another data structure you might consider:
import collections as ct
import more_itertools as mit
def locate_indices(a, b):
"""Return a dictionary of `a` index keys found at `b` indices."""
dd = ct.defaultdict(list)
for i, y in enumerate(a):
idxs = list(mit.locate(b, lambda z: z == y))
if idxs: dd[i].extend(idxs)
return dd
locate_indices(list1_, list2_)
# defaultdict(list, {0: [3], 1: [1], 3: [0, 6], 6: [4, 5], 7: [2]})
Note the index of list a is the key in the dictionary. All indices in list b that share the same value are appended.
A defaultdict was used since it is helpful in building dictionaries with list values. See more on the third-party tool more_itertools.locate(), which simply yields all indices that satisfy the lambda condition - an item in list a is also found in b.
from itertools import product
from collections import defaultdict
def mathcing_indices(*lists):
d = defaultdict(lambda: tuple([] for _ in range(len(lists))))
for l_idx, l in enumerate(lists):
for i, elem in enumerate(l):
d[elem][l_idx].append(i)
return sorted([tup for _, v in d.items() for tup in product(*v)])
This solution builds a dictionary that tracks the indices that values appear at in the input lists. So if the value 5 appears at indices 0 and 2 of the first list and index 3 of the second, the value for 5 in the dictionary would be ([0, 2], [3])
It then uses itertools.product to build all the combinations of those indices.
This looks more complicated than the other answers here, but because it is O(nlogn) and not O(n**2) it is significantly faster, especially for large inputs. Two length 1000 lists of random numbers 0-1000 complete 100 tests in ~.4 seconds using the above algorithm and 6-13 seconds using some of the others here
Here is a solution that runs in O(n log n):
ind1 = numpy.argsort(_list)
ind2 = numpy.argsort(_list2)
pairs = []
i = 0
j = 0
while i<ind1.size and j<ind2.size:
e1 = _list[ind1[i]]
e2 = _list2[ind2[j]]
if e1==e2:
pairs.append((ind1[i],ind2[j]))
i = i + 1
j = j + 1
elif e1<e2:
i = i +1
elif e2<e1:
j = j + 1
print(pairs)

Compare occurrences of shared items between lists

Ok, for a fun project I'm working on in order to learn some python I'm hitting a wall with what should be a basic task: I need to compare lists for the times items shared among the lists occur in each list. Using
shared_items = set(alist).intersection(blist)
gives me the items sharedbetwen the lists, but it does not tell me, how often those items occur in each list.
I tried loops like this for example:
def the_count(alist,blist):
c = 0
for x in alist:
for y in blist:
if x == y:
c += 1
return c
but that doesn't do the trick.
Another attempt was to use Counter:
c = Counter(alist)
b = Counter(blist)
But trying to loop over the Counter results failed too, last try was
a = Counter(alist)
b = Counter(blist)
for key, val in a:
if key in b:
val1 = b[key]
if val < val1:
print b[key]
else:
print a[key]
You almost had it using the set intersection. Since that gives you the common elements amongst both lists, all you have to do now is loop over that and count the elements. One way could be:
list1 = [0, 1, 2, 3, 1, 2, 3, 4, 3, 2]
list2 = [1, 4, 3, 5, 2, 1, 0, 2, 7, 8]
shared = set(list1).intersection(list2)
# Now, loop over the elements and create a dictionary using a generator.
# The key will be the shared element, and the value would be a tuple
# which corresponds to the counts of the first list and the second list, respectively
counts = {num:(list1.count(num), list2.count(num)) for num in shared}
counts now contains:
{
0: (1, 1),
1: (2, 2),
2: (3, 2),
3: (3, 1),
4: (1, 1)
}
This can further be abstracted into a function similar to:
def count_shared_elements(list1, list2):
shared = set(list1).intersection(list2)
return {num:(list1.count(num), list2.count(num)) for num in shared}
Using list (dict) as jrd1 pointed comprehension:
>>> list1 = [0, 1, 2, 3, 1, 2, 3, 4, 3, 2]
>>> list2 = [1, 4, 3, 5, 2, 1, 0, 2, 7, 8]
>>> {i:(list1.count(i), list2.count(i)) for i in set(list1) & set(list2)}
{0: (1, 1), 1: (2, 2), 2: (3, 2), 3: (3, 1), 4: (1, 1)}
Take a look at the answers linked in the question comments, another way to do this would be like this:
for a in alist:
c+= blist.count(a)
Best way is to get the unique items from two lists and check the count of those distinct numbers in each list.
for distinct_num in set(alist + blist):
print(alist.count(distinct_num))
print(blist.count(distinct_num))

Categories

Resources