Remove elements from nested list - Python - python

data = [['A', 'B', 'C', 'D'],
['E', 'F', 'G'],
['I', 'J'],
['A', 'B', 'C', 'E', 'F']]
I would like to remove unpopular elements (appearing only once) from the lists. So the results should look like this:
data = [['A', 'B', 'C'],
['E', 'F'],
['A', 'B', 'C', 'E', 'F']]
I was able to count the frequency of each element using the following codes:
from collections import Counter
Counter(x for sublist in data for x in sublist)
#output
Counter({'A': 2, 'C': 2, 'B': 2, 'E': 2, 'F': 2, 'D': 1, 'G': 1, 'I': 1, 'J': 1})
However, I am not sure how to use this count information to remove unpopular elements from the list. Any help?

Generate the new list based on the frequency information.
The following code uses nested list comprehension to do that:
from collections import Counter
freq = Counter(x for sublist in data for x in sublist)
data = [[x for x in row if freq[x] > 1] for row in data] # Remove non-popular item
data = [row for row in data if row] # Remove empty rows
# data => [['A', 'B', 'C'], ['E', 'F'], ['A', 'B', 'C', 'E', 'F']]

The complexity is similar. Just use map and filter function to make the code more pythonic.
from collections import Counter
data = [['A', 'B', 'C', 'D'],
['E', 'F', 'G'],
['I', 'J'],
['A', 'B', 'C', 'E', 'F']]
counter = Counter({'A': 2, 'C': 2, 'B': 2, 'E': 2, 'F': 2, 'D': 1, 'G': 1, 'I': 1, 'J': 1})
result = map(lambda row: filter(lambda x: counter.get(x) > 1, row), data)
print result

Related

Extract all possible combinations of unique elements in dict of lists

I have this input:
d = {'a': ['A', 'B', 'C'], 'b': ['A', 'B', 'C'], 'c': ['D', 'E'], 'd': ['E', 'F', 'G']}
How can I extract all the possible unique samplings per list?
One of the possible output is for example:
d = {'a': 'A', 'b': 'B', 'c': 'D', 'd': 'E'}
or
d = {'a': 'B', 'b': 'A', 'c': 'E', 'd': 'F'}
and so on..
Any idea?
Thank you
This is what you are looking for
import itertools
keys, values = zip(*d.items())
permutations_dicts = [dict(zip(keys, v)) for v in itertools.product(*values)]

'Counter' object has no attribute 'count'

There are two lists and I want to check how many of elements are duplicate. Assuming list one is l1 = ['a', 'b', 'c', 'd', 'e'] and list two is l2 = ['a', 'f', 'c', 'g']. Since a and c are in both lists, therefore, the output should be 2 which means there are two elements that repeated in both lists. Below is my code and I want to count how many 2 are in counter. I am not sure how to count that.
l1 = ['a', 'b', 'c', 'd', 'e']
l2 = ['a', 'f', 'c', 'g']
from collections import Counter
c1 = Counter(l1)
c2 = Counter(l2)
sum = c1+c2
z=sum.count(2)
What you want is set.intersection (if there are no duplicates in each list):
l1 = ['a', 'b', 'c', 'd', 'e']
l2 = ['a', 'f', 'c', 'g']
print(len(set(l1).intersection(l2)))
Output:
2
Every time we use a counter it converts the lists into dict. So it is throwing the error. You can simply change the number of lists and run the following code to get the exact number of duplicate values.
# Duplicate elements in 2 lists
l1 = ['a', 'b', 'c', 'd', 'e']
l2 = ['a', 'f', 'c', 'g']# a,c are duplicate
from collections import Counter
c1 = Counter(l1)
c2 = Counter(l2)
sum = c1+c2
j = sum.values()
print(sum)
print(j)
v = 0
for i in j:
if i>1:
v = v+1
print("Duplicate in lists:", v)
Output:
Counter({'a': 2, 'c': 2, 'b': 1, 'd': 1, 'e': 1, 'f': 1, 'g': 1})
dict_values([2, 1, 2, 1, 1, 1, 1])
Duplicate in lists: 2

Converting paired list values to dictionary

I have a list of pairs like the following one:
[['A', 'B'],
['C', 'E'],
['F', 'D'],
['C', 'D'],
['D', 'E'],
['G', 'E'],
['B', 'A'],
['H', 'G'],
['A', 'F'],
['E', 'A']]
I want to generate a dictionary with the first value in each pair as keys and the second one as value like the following:
{'A': ['B', 'F'],
'B': ['A'],
'C': ['E', 'D'],
'D': ['E'],
'E': ['A'],
'F': ['D', 'E'],
'G': ['E'],
'H': ['G']}
I used the following code, but didn't reached the desired outcome:
keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
graph = {}
graph = graph.fromkeys(keys, [])
for row in pairs:
(graph[row[0]]).append(row[1])
dict.fromkeys will set all your values to the same list object! Use dict.setdefault instead which will create a new list for each unknown key:
graph = {}
for row in pairs:
graph.setdefault(row[0], []).append(row[1])
Alternatively, use a collection.defaultdict
from collections import defaultdict
graph = defaultdict(list)
for row in pairs:
graph[row[0]].append(row[1])
Or, more elegantly:
for v1, v2 in in pairs:
graph[v1].append(v2)

How to count the occurance of all elements of list in python?

I have to write all the elements separately along with their count.
It's the program i have made. It is counting correctly but not giving required output
The output is like this
I want output to be like this. All digits showing individual complete count
You can count the number of occurrence of a special element with count() method:
grades = ['b', 'b', 'f', 'c', 'b', 'a', 'a', 'd', 'c', 'd', 'a', 'a', 'b']
letters = ['a', 'b', 'c', 'd', 'f']
print(list(map(lambda letter: {letter: grades.count(letter)}, letters)))
Output:
[{'a': 4}, {'b': 4}, {'c': 2}, {'d': 2}, {'f': 1}]
If you want to do this without using letters. you can do this:
grades = ['b', 'b', 'f', 'c', 'b', 'a', 'a', 'd', 'c', 'd', 'a', 'a', 'b']
print(list(map(lambda letter: {letter: grades.count(letter)}, set(grades))))
Output:
[{'f': 1}, {'b': 4}, {'c': 2}, {'d': 2}, {'a': 4}]
For your expected output:
grades = ['b', 'b', 'f', 'c', 'b', 'a', 'a', 'd', 'c', 'd', 'a', 'a', 'b']
occurrence = map(lambda letter: (letter, grades.count(letter)), set(grades))
for item in occurrence:
print(f"{item[0]}={item[1]}")
Output:
c=2
b=4
d=2
f=1
a=4
Update
You can use defaultdict() to count the occurrence of each element:
from collections import defaultdict
grades = ['b', 'b', 'f', 'c', 'b', 'a', 'a', 'd', 'c', 'd', 'a', 'a', 'b']
occurrence = defaultdict(lambda: 0)
for character in grades:
occurrence[character] += 1
for key, value in occurrence.items():
print(f"{key}={value}")
Output:
b=4
f=1
c=2
a=4
d=2

Custom list of lists into dictionary

I have list of lists and I wish to create a dictionary with length of each element as values. I tried the following:
tmp = [['A', 'B', 'E'], ['B', 'E', 'F'], ['A', 'G']]
tab = []
for line in tmp:
tab.append(dict((k, len(tmp)) for k in line))
But it gives the output as:
[{'A': 3, 'B': 3, 'E': 3}, {'B': 3, 'E': 3, 'F': 3}, {'A': 3, 'G': 3}]
What is the modification that I should make to get the output:
{['A', 'B', 'E']:3, ['B', 'E', 'F']:3, ['A', 'G']:2}
Thanks in advance.
AP
You can't use list objects as dictionary keys, they are mutable and unhashable. You can convert them to tuple. Also note that you are looping over each sub list. You can use a generator expression by only looping over the main list:
In [3]: dict((tuple(sub), len(sub)) for sub in tmp)
Out[3]: {('A', 'B', 'E'): 3, ('A', 'G'): 2, ('B', 'E', 'F'): 3}
{tuple(t):len(t) for t in tmp}
Input :
[['A', 'B', 'E'], ['B', 'E', 'F'], ['A', 'G']]
Output :
{('A', 'G'): 2, ('A', 'B', 'E'): 3, ('B', 'E', 'F'): 3}
Dictionnary does not accept list as key, but tuple

Categories