0

I've been using the solution provided in Sorting_Dictionary to sort a dictionary according to values.I know dictionaries cannot be as such sorted but a list of sorted tupples can be obtained.

Complete code:

import sys
import pprint


def helper(filename):
    Word_count={}
    f=open(filename)
    for line in f:
        words=line.split()
        for word in words:
            word=word.lower()
            Word_count.setdefault(word,0)
            Word_count[word]+=1
    f.close()
    return Word_count

def print_words(filename):
    Word_count_new=helper(filename)
    sorted_count=sorted(Word_count_new.items(),key=Word_count_new.get,reverse=True)
    for word in sorted_count:
      pprint.pprint(word)

def print_top(filename):
    word_list=[]
    Word_count=helper(filename)
    word_list=[(k,v) for k,v in Word_count.items()]
    for i in range(20):
        print word_list[i] + '\n'
###

# This basic command line argument parsing code is provided and
# calls the print_words() and print_top() functions which you must define.
def main():
  if len(sys.argv) != 3:
    print 'usage: ./wordcount.py {--count | --topcount} file'
    sys.exit(1)

  option = sys.argv[1]
  filename = sys.argv[2]
  if option == '--count':
    print_words(filename)
  elif option == '--topcount':
    print_top(filename)
  else:
    print 'unknown option: ' + option
    sys.exit(1)

if __name__ == '__main__':
  main()

This function produces problem:

def print_words(filename):
    Word_count_new=helper(filename)
    sorted_count=sorted(Word_count_new.items(),key=Word_count_new.get,reverse=True)
    for word in sorted_count:
        pprint.pprint(word)

here helper is a method which returns a dictionary which is to be sorted. The dictionary is like this {Dad:1, Mom:2, baby:3}

But this doesn't produce a sorted list of tupples. Instead the output is somewhat random like this

('he', 111)
("hot-tempered,'", 1)
('made', 29)
('wise', 2)
('whether', 11)
('wish', 21)
('scroll', 1)
('eyes;', 1)
('this,', 17)
('signed', 2)
('this.', 1)

How can we explain this behaviour?

Prabhat Sharma
  • 76
  • 1
  • 12
  • What is `helper` and what does its `get()` method do? – DYZ Jun 20 '17 at 00:09
  • Welcome to StackOverflow. Please read and follow the posting guidelines in the help documentation. [Minimal, complete, verifiable example](http://stackoverflow.com/help/mcve) applies here. We cannot effectively help you until you post your MCVE code and accurately describe the problem. We should be able to paste your posted code into a text file and reproduce the problem you described. – Prune Jun 20 '17 at 00:13
  • I've updated about helper but this get() method is standard which returns the value corresponding to a key and returns default value of key is not present – Prabhat Sharma Jun 20 '17 at 00:13
  • 1
    you should just use `sorted_count=sorted(Word_count_new.items(),key=lambda x:x[1],reverse=True)` – danche Jun 20 '17 at 00:16
  • Your code, as shown, looks ok. The problem must be in in the `helper`. Did you implement it yourself? If so, show us the code. If not, what module does it come from? – DYZ Jun 20 '17 at 00:17

1 Answers1

0
 sorted_count = sorted(Word_count_new.items(), key=lambda x: x[1], reverse=True)

According to the documentation for sorted (https://docs.python.org/3/library/functions.html#sorted), the second argument is a function that creates a comparison key from each list element, so not the dict as a whole.

Word_count_new.items() returns an iterable (in python3, list in python2) of tuples, which is what's passed to your key function. If you want your comparison key to be based of the work frequency (the second element), you want to return the second element in this function (x[1] where x is the individual tuple getting compared).

To also explain the random output you got, your key was Word_count_new.get. Since your dict does not have tuples as keys, the default value will be None.

BrockLee
  • 931
  • 2
  • 9
  • 24
  • "_passing a tuple to this may just cause some undefined behavior_" - Why so? – DYZ Jun 20 '17 at 00:20
  • 3
    The behavior of passing the `tuple` is perfectly defined: `.get` will not find that tuple, and return `None`. Since `sorted` is guaranteed stable, and `None` always compares equal to `None`, everything will return in the same order that would normally result from iterating over `.items`. – juanpa.arrivillaga Jun 20 '17 at 00:20
  • Thanks!! It worked. But the get function also creates the value as the comparison key then why doesn't it work? – Prabhat Sharma Jun 20 '17 at 00:21
  • 1
    @PrabhatSharma " the get function also creates the value as the comparison key" huh? What do you mean? – juanpa.arrivillaga Jun 20 '17 at 00:22
  • The get function does not create the value as the comparison key. The `key` keyword in the `sort()` function takes in a function that is applied to each element of the iterable. In this case, the iterable is a list of tuples, so the `key` function will be applied to tuples. The `.get` function will not be applied to the dictionary itself, but to each tuple inside the list of tuples. – victor Jun 20 '17 at 00:23
  • @juanpa.arrivillaga and DYZ. My bad. I forgot that get accepts a default value. None in this case. I thought the default had to be a second positional argument and not a keyword. – BrockLee Jun 20 '17 at 00:24
  • I'm still a noob in python. just started two days ago, so don't mind it. According to my understanding the get function will return the value from the dictionary which will behave just like x[1] i.e. the comparison key – Prabhat Sharma Jun 20 '17 at 00:25
  • 1
    @LeoCHan actually, the default value has a default value! – juanpa.arrivillaga Jun 20 '17 at 00:25
  • Ohh! now I understood @Victor C – Prabhat Sharma Jun 20 '17 at 00:26
  • @juanpa.arrivillaga The function passed as 'key' is called with the tuple as its argument and creates a comparison key (this is what they refer the value as in the python docs https://docs.python.org/3/library/functions.html#sorted) – BrockLee Jun 20 '17 at 00:27
  • I was referring to the default value of `.get` – juanpa.arrivillaga Jun 20 '17 at 00:32