2

I have something like this in Python to count the frequency of characters in a text, but i can't sort the values on the dictionary "v".

abcedario='abcdefghijklmnopqrstvuxwyz'
v = {}
count = 0
for c in abcedario:
    count = 0
    for char in text:
        if c == char:
            count = count +1
            v[c] = count
            sorted(v.items(), key=lambda x:x[1])
print v

I try to search here on stackoverflow but never solve my problem, the aspect of the output is this:

{'a': 2, 'b': 4, 'e': 4, 'd': 36, 'g': 31, 'f': 37, 'i': 14, 'h': 4, 'k': 51, 'j': 31, 'l': 34, 'n': 18, 'q': 13, 'p': 2, 'r': 9, 'u': 1, 't': 1, 'w': 36, 'v': 15, 'y': 14, 'x': 8, 'z': 10}

I want sort by value, so it's different from other posts.

PRVS
  • 1,612
  • 4
  • 38
  • 75
  • 1
    The bigger problem is that `sorted` returns a new collection instead of sorting inplace – WorldSEnder Oct 09 '15 at 13:58
  • 1
    Possible duplicate of [How can I sort a dictionary by key?](http://stackoverflow.com/questions/9001509/how-can-i-sort-a-dictionary-by-key) – tmdavison Oct 09 '15 at 14:00
  • 1
    @ZdaR `OrderedDict`, presumably? – jonrsharpe Oct 09 '15 at 14:01
  • 1
    I don't think this is a duplicate, the other question is about sorting by key. – Vlad Oct 09 '15 at 14:02
  • 1
    BTW, your code is _very_ inefficient. You don't need to have a nested pair of `for` loops. – PM 2Ring Oct 09 '15 at 14:08
  • @jonrsharpe, exactly, my bad. – ZdaR Oct 09 '15 at 14:56
  • @tom is not duplicated because i wanted sort by value. – PRVS Oct 09 '15 at 20:17
  • @PM2Ring I have other text above the code, that i don't show here, that's because two for loops. – PRVS Oct 09 '15 at 20:18
  • @PRVS, ok, so it was the wrong duplicate. There are others that solve the sort by value: For example, this one with 1200+ upvotes http://stackoverflow.com/questions/613183/sort-a-python-dictionary-by-value – tmdavison Oct 09 '15 at 20:21
  • @tom the solutions present in this question don't solve mine, you can see by the question that i mark with correct. – PRVS Oct 09 '15 at 20:23
  • @PRVS: Ok, but you could use the `str` `.isalpha()` and `.islower()` methods to speed up testing if a char is lower-case alphabetic (these methods are both locale-aware), or if `abcedario` isn't actually the full alphabet you can still speed up testing by making it a `set` or `frozenset`. Also, to count frequency you can use a [Counter](https://docs.python.org/2/library/collections.html#collections.Counter); if you don't want to use Counter, there's an efficient way to do the same thing with a plain `dict` in the answers to http://stackoverflow.com/q/3496518/4014959 – PM 2Ring Oct 10 '15 at 07:40
  • @PVRS the accepted answer to that question includes a solution that works almost the same as your accepted solution (but using `operator.itemgetter` instead of the `lambda` function below), so I disagree that it doesn't solve your problem. Anyway, glad that you found a solution to your problem! – tmdavison Oct 11 '15 at 23:43

3 Answers3

2

A python dictionary is an unordered collection of items. Therefore, it can't be sorted. Try looking into OrderedDict from collections.

Ivana Balazevic
  • 148
  • 1
  • 9
2

If you just want to print them in order, just print the output of sorted:

abcedario='abcdefghijklmnopqrstvuxwyz'
v = {}
count = 0
for c in abcedario:
    count = 0
    for char in text:
        if c == char:
            count = count +1
            v[c] = count
print sorted(v.items(), key=lambda x:x[1])

For text = "helloworld" you get:

[('e', 1), ('d', 1), ('h', 1), ('r', 1), ('w', 1), ('o', 2), ('l', 3)]  
Vlad
  • 18,195
  • 4
  • 41
  • 71
2

you can use Counter

from collections import Counter
text = "I have something like this in Python to count the frequency of characters in a text, but i can't sort the values on the dictionary"
print(Counter(text))

output:

Counter({' ': 24, 't': 15, 'e': 11, 'n': 9, 'h': 8, 'i': 8, 'o': 8, 'a': 7, 'c': 6, 's': 5, 'r': 5, 'u': 4, 'y': 3, 'f': 2, 'l': 2, 'v': 2, "'": 1, 'q': 1, 'd': 1, 'I': 1, 'm': 1, 'g': 1, 'b': 1, 'x': 1, ',': 1, 'P': 1, 'k': 1})
Saket Mittal
  • 3,726
  • 3
  • 29
  • 49
LetzerWille
  • 5,355
  • 4
  • 23
  • 26