2

I am trying to get the sorted output from following program.

"""Count words."""
    # TODO: Count the number of occurences of each word in s

    # TODO: Sort the occurences in descending order (alphabetically in case of ties)

    # TODO: Return the top n words as a list of tuples 


from operator import itemgetter
def count_words(s, n):
    """Return the n most frequently occuring words in s."""

    t1=[]
    t2=[]
    temp={}
    top_n={}

    words=s.split()
    for word in words:
        if word not in temp:
            t1.append(word)
            temp[word]=1
        else:
            temp[word]+=1
    top_n=sorted(temp.items(), key=itemgetter(1,0),reverse=True)

    print top_n

    return 


def test_run():
    """Test count_words() with some inputs."""
    count_words("cat bat mat cat bat cat", 3)
    count_words("betty bought a bit of butter but the butter was bitter", 3)


if __name__ == '__main__':
    test_run()

This program output is like:

[('cat', 3), ('bat', 2), ('mat', 1)]

[('butter', 2), ('was', 1), ('the', 1), ('of', 1), ('but', 1), ('bought', 1), ('bitter', 1), ('bit', 1), ('betty', 1), ('a', 1)]

but I need in the form like:

[('cat', 3), ('bat', 2), ('mat', 1)]

[('butter', 2), ('a', 1),('betty', 1),('bit', 1),('bitter', 1) ... rest of them here]

COuld you please let me know the best possible way?

4
  • 2
    They are immutable, but sort-able. And dict wouldn't fit here, unless you only use the array part of dictionary. Or if you change the question altogether. Lists would be an option, though. Commented Jul 17, 2016 at 19:16
  • can u guys suggest any modification in the above code only so that it gives the desired output Commented Jul 17, 2016 at 19:18
  • What is (<word>, <count>) Commented Jul 17, 2016 at 19:21
  • typo mistake in my local editor.. removed Commented Jul 17, 2016 at 19:22

4 Answers 4

3

You need to change the key function you're giving to sorted, since the items in your desired output need to be sorted in descending order by count but ascending order alphabetically. I'd use a lambda function:

top_n = sorted(temp.items(), key=lambda item: (-item[1], item[0]))

By negating the count, an ascending sort gets you the desired order.

Sign up to request clarification or add additional context in comments.

2 Comments

can we limit the number of items to be return by sorted by passing any argument ?
No, sorted always sorts the whole list. To get just the first n values, use a slice: top_n = top_n[:n]
0

You can change:

top_n=sorted(temp.items(), key=itemgetter(1,0),reverse=True)

To:

temp2=sorted(temp.items(), key=itemgetter(0),reverse=False)
top_n=sorted(temp2.items(), key=itemgetter(1),reverse=True)

and thanks to the Sort Stability you will be good

2 Comments

how temp2 shud be defined here? like this temp2={} ??
@ManishKumar the first line define temp2, and the seconed use it. you don't need to initialize it.
0

Instead of itemgetter, use lambda t:(-t[1],t[0]) and drop the reverse=True:

top_n=sorted(temp.items(), key=lambda t:(-t[1],t[0]))

This returns the same thing as itemgetter(1,0) only with the first value inverted so that higher numbers will be sorted before lower numbers.

Comments

0
def count_words(s, n):
"""Return the n most frequently occuring words in s."""

    t1=[]
    t2=[]
    temp={}
    top_n={}

    words=s.split()
    for word in words:
        if word not in temp:
            t1.append(word)
            temp[word]=1
        else:
            temp[word]+=1
    top_n=sorted(temp.items(), key=lambda t: (t[1], t[0]),reverse=True)

    print top_n

    return 


def test_run():
"""Test count_words() with some inputs."""
    count_words("cat bat mat cat bat cat", 3)
    count_words("betty bought a bit of butter but the butter was bitter", 3)


if __name__ == '__main__':
    test_run() 

I used lambda instead of itemgetter and in other apps I've written, lambda seems to work.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.