0

Im trying to get the output from my dictionary to be ordered from their values in stead of keys

Question:

ValueCount that accepts a list as a parameter. Your function will return a list of tuples. Each tuple will contain a value and the number of times that value appears in the list

Desired outcome

>>> data = [1,2,3,1,2,3,5,5,4]
    >>> ValueCount(data)
            [(1, 2), (2, 2), (5, 1), (4, 1)]

My code and outcome

def CountValues(data):
    dict1 = {}
    for number in data:
        if number not in dict1:
            dict1[number] = 1
        else: 
            dict1[number] += 1
    tuple_data = dict1.items()
    lst = sorted(tuple_data)
    return(lst)

>>>[(1, 2), (2, 2), (3, 2), (4, 1), (5, 2)]

How would I sort it ascendingly by using the values instead of keys.

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
  • Instead of manually counting use a [`Counter`](https://docs.python.org/3/library/collections.html#collections.Counter), and instead of sorting use its [`most_common`](https://docs.python.org/3/library/collections.html#collections.Counter.most_common) method. – Tomerikoo Mar 23 '20 at 11:08

3 Answers3

1

If you want to sort by the values(second item in each tuple), specify key:

sorted(tuple_data, key=lambda x: x[1])

Or with operator.itemgetter:

sorted(tuple_data, key=operator.itemgetter(1))

Also as a side note, your counting code:

dict1 = {}
for number in data:
    if number not in dict1:
        dict1[number] = 1
    else: 
        dict1[number] += 1

Can be simplified with collections.Counter:

dict1 = collections.Counter(data)

With all the above in mind, your code could look like this:

from operator import itemgetter
from collections import Counter

def CountValues(data):
    counts = Counter(data)
    return sorted(counts.items(), key=itemgetter(1))

print(CountValues([1,2,3,1,2,3,5,5,4]))
# [(4, 1), (1, 2), (2, 2), (3, 2), (5, 2)]
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
1

You can use the sorted with the help of key parameter. it is not a in-place sorting . Thus it never modifies the original array.

for more

In [18]:  data = [1,2,3,1,2,3,5,5,4]

In [19]:  from collections import Counter

In [20]: x=Counter(data).items()


#Sorted OUTPUT
In [21]: sorted(list(x), key= lambda i:i[1] )   
Out[21]: [(4, 1), (1, 2), (2, 2), (3, 2), (5, 2)]

In [22]: x
Out[22]: dict_items([(1, 2), (2, 2), (3, 2), (5, 2), (4, 1)])
halfer
  • 19,824
  • 17
  • 99
  • 186
teddcp
  • 1,514
  • 2
  • 11
  • 25
  • If already using a `Counter`, you can use its `most_common` method instead of sorting. If ascending order is required, you can do `Counter(data).most_common()[::-1]` – Tomerikoo Mar 23 '20 at 11:06
-2

"Sort" function uses first element of data. To sort dictionary by its values you can use for-loop for values:

d={1:1,2:2,5:2,4:3,3:2}
x=[]
for i in set(sorted(d.values())):
    for j in sorted(d.items()):
        if j[1]==i:
            x.append(j)
print(x)

if you don't convert sorted(d.values()) to set{} , it will check every value, even there are same numbers. For example if your values list is [1,2,2,3] , it will check items for value "2" two times and as a result your sorted list will contain repeated data which both have value "2" . But set{} keeps only one of each element and in this case, for-loop will check every different value of d.values() . And if there are items with a same value, code will sort them by keys because of sorted(d.items()) . (to understand better you can use this code without that set{} and use d.items() instead of sorted(d.items()))

Deastra
  • 1
  • 2
  • 1
    This is not a good way to sort by the values, it is needlessly inefficient, this can be done in O(M*logN) time, but here you are doing something like O(M**2*(logN )**2) – juanpa.arrivillaga Mar 21 '20 at 04:25