Python-compare and sort two lists of numbers and return them in ascending order
Question:
I have two lists:
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
I want to return the list of elements that appear only in the first list but not in the second and the list should be sorted ascending so the result is like this:
[1, 3, 2, 4]
So far I have this:
def sorted_nums(list_1,list2_2):
c = (set(list_1) - set(list_2))
d = dict.fromkeys(c, 0)
for index in list_1:
if index in c:
d[index]+=1
return d
a = sorted_nums(list_1,list_2)
b = sorted(a.items(), key = lambda x: x[1])
print(b)
and it returns this:
[(1,2), (3,2), (2,3), (4,5)]
Could you help me to change the last part of the code so that I get the result I want?
Answers:
Method 1:
By using sorted(array, key = list_1.count)
to sort by occurrence but this will be slow.
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
def sorted_nums(list_1,list2_2):
return sorted(list(set(list_1) - set(list_2)), key = list_1.count)
sorted_nums(list_1, list_2)
Method 2 (Credits):
By using Counter
. This is a faster approach. :
from collections import Counter
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
counter_1 = Counter(list1)
def sorted_nums(list_1,list2_2):
return sorted(counter_1.keys() - set(list2), key=counter_1.get)
sorted_nums(list_1, list_2)
Output:
[1, 3, 2, 4]
use set
operations
a = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
b = [5, 5, 5, 6, 6, 7]
c = sorted(list(set(a) - set(b)))
print(c)
list(dict.fromkeys(list_1))
this is working same as set
but keep order of elements
def sorted_nums(list_1,list_2):
return tuple(filter(lambda x: x not in set(list_2), list(dict.fromkeys(list_1))))
All you need is a map
def sorted_nums(list_1,list2_2):
c = (set(list_1) - set(list_2))
d = dict.fromkeys(c, 0)
for index in list_1:
if index in c:
d[index]+=1
return d
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
a = sorted_nums(list_1,list_2)
b = list(map(lambda x:x[0],sorted(a.items(), key = lambda x: x[1]))) ## changed here
print(b)
[1, 3, 2, 4]
Apply function lambda x:x[0]
over each and every elements using map
You already have it sorted. So you need to extract the first element?
print([x[0] for x in b])
You just want to sort by the occurance (counts) of lis1, taking the set-difference from the second list:
>>> list1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
>>> list2 = [5, 5, 5, 6, 6, 7]
>>> from collections import Counter
>>> counts1 = Counter(list1)
>>> sorted(counts1.keys() - set(list2), key=counts1.get)
[1, 3, 2, 4]
If you’re OK with the default order for tied counts, this is quite succinct:
from collections import Counter
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
blacklist = set(list_2)
c = Counter(i for i in list_1 if i not in blacklist)
[n for n,_ in reversed(c.most_common())]
The output is [3, 1, 2, 4]
(note the counts for 1 and 3 are the same).
If you can rely on the ordering of your list_1 to be as it is in your example (all clusters are consecutive) you can do a bit better using itertools.groupby
:
import itertools.groupby
c = sorted((len(list(g)), i) for i, g in itertools.groupby(list_1) if i not in blacklist)
[i for _, i in c]
Output is [1, 3, 2, 4]
My interpretation of the question leads me to this:
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
d = dict()
list_2_s = set(list_2)
for e in list_1:
if e not in list_2_s:
d[e] = d.setdefault(e, 0) + 1
lst = [t[1] for t in sorted((v, k) for k, v in d.items())]
print(lst)
Output:
[1, 3, 2, 4]
I have two lists:
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
I want to return the list of elements that appear only in the first list but not in the second and the list should be sorted ascending so the result is like this:
[1, 3, 2, 4]
So far I have this:
def sorted_nums(list_1,list2_2):
c = (set(list_1) - set(list_2))
d = dict.fromkeys(c, 0)
for index in list_1:
if index in c:
d[index]+=1
return d
a = sorted_nums(list_1,list_2)
b = sorted(a.items(), key = lambda x: x[1])
print(b)
and it returns this:
[(1,2), (3,2), (2,3), (4,5)]
Could you help me to change the last part of the code so that I get the result I want?
Method 1:
By using sorted(array, key = list_1.count)
to sort by occurrence but this will be slow.
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
def sorted_nums(list_1,list2_2):
return sorted(list(set(list_1) - set(list_2)), key = list_1.count)
sorted_nums(list_1, list_2)
Method 2 (Credits):
By using Counter
. This is a faster approach. :
from collections import Counter
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
counter_1 = Counter(list1)
def sorted_nums(list_1,list2_2):
return sorted(counter_1.keys() - set(list2), key=counter_1.get)
sorted_nums(list_1, list_2)
Output:
[1, 3, 2, 4]
use set
operations
a = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
b = [5, 5, 5, 6, 6, 7]
c = sorted(list(set(a) - set(b)))
print(c)
list(dict.fromkeys(list_1))
this is working same as set
but keep order of elements
def sorted_nums(list_1,list_2):
return tuple(filter(lambda x: x not in set(list_2), list(dict.fromkeys(list_1))))
All you need is a map
def sorted_nums(list_1,list2_2):
c = (set(list_1) - set(list_2))
d = dict.fromkeys(c, 0)
for index in list_1:
if index in c:
d[index]+=1
return d
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
a = sorted_nums(list_1,list_2)
b = list(map(lambda x:x[0],sorted(a.items(), key = lambda x: x[1]))) ## changed here
print(b)
[1, 3, 2, 4]
Apply function lambda x:x[0]
over each and every elements using map
You already have it sorted. So you need to extract the first element?
print([x[0] for x in b])
You just want to sort by the occurance (counts) of lis1, taking the set-difference from the second list:
>>> list1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
>>> list2 = [5, 5, 5, 6, 6, 7]
>>> from collections import Counter
>>> counts1 = Counter(list1)
>>> sorted(counts1.keys() - set(list2), key=counts1.get)
[1, 3, 2, 4]
If you’re OK with the default order for tied counts, this is quite succinct:
from collections import Counter
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
blacklist = set(list_2)
c = Counter(i for i in list_1 if i not in blacklist)
[n for n,_ in reversed(c.most_common())]
The output is [3, 1, 2, 4]
(note the counts for 1 and 3 are the same).
If you can rely on the ordering of your list_1 to be as it is in your example (all clusters are consecutive) you can do a bit better using itertools.groupby
:
import itertools.groupby
c = sorted((len(list(g)), i) for i, g in itertools.groupby(list_1) if i not in blacklist)
[i for _, i in c]
Output is [1, 3, 2, 4]
My interpretation of the question leads me to this:
list_1 = [1,1, 2,2,2, 3,3, 4, 4, 4 ,4, 4, 5,5,5,5]
list_2 = [5, 5, 5, 6, 6, 7]
d = dict()
list_2_s = set(list_2)
for e in list_1:
if e not in list_2_s:
d[e] = d.setdefault(e, 0) + 1
lst = [t[1] for t in sorted((v, k) for k, v in d.items())]
print(lst)
Output:
[1, 3, 2, 4]