5

I have code to sort a list of tuples:

s = "betty bought a bit of butter but the butter was bitter"
words = s.split()
l = []
k = []
unique_words = sorted(set(words))
for word in unique_words:
     k.append(word)
     l.append(words.count(word))

z = zip(k,l)
print z
reversed(sorted(z, key=lambda x: x[1]))
print z

z is the same, list doesn't get sorted or even reversed.

I am trying to sort by the integer value of count.

3
  • how should the output look like? Commented Aug 20, 2016 at 2:00
  • @vkp I want to sort by the count to get the list. That is the output (sorted by counts). Thanks. Commented Aug 20, 2016 at 2:02
  • The first 60% of your code isn't required for an minimal reproducible example. All you really need to demonstrate the problem is a hard-coded z list of word:count tuples, followed by the last three lines. Commented Aug 20, 2016 at 4:27

5 Answers 5

6

For an in-place sort, you should use z.sort().

If you insist on using sorted, then send the value back to z.

So, use either,

z.sort(key = lambda x:x[1])
z.reverse()

Or,

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

Or, a more sophisticated solution could be:

z = sorted(z, key=lambda x: x[1], reverse= True)

As a matter of fact, you can get the end result more easily by using collections.Counter()

from collections import Counter 
z = sorted(Counter(s.split()).items(), key = lambda x:x[1], reverse = True)

Sorting by two multiple keys are fine, you can pass them as a tuple. In your case, the solution would be:

# first sort by negatives of the second item, then alphabetically. 
z = sorted(z, key=lambda x: (-x[1],x[0]))

Output:

[('butter', 2), ('a', 1), ('betty', 1), ('bit', 1), ('bitter', 1),
('bought', 1), ('but', 1), ('of', 1), ('the', 1), ('was', 1)]
Sign up to request clarification or add additional context in comments.

10 Comments

I get AttributeError Traceback (most recent call last) <ipython-input-159-dde64c2dc4e9> in <module>()
Hi, using z.sort() gives me the error: File "<ipython-input-169-2d6ad2c8146e>"
@John77 You put the tag python-2.7, but the errors you are getting imply Python3. Can you please clarify which python version you are using?
@SethMMorton I installed anaconda 2.7 and am using the jupyter notebook.
@John77 OK. As an FYI, you aren't copying the entire traceback... the last line has all the useful bits, but you are only copying the first line, so we are left to guess as to what the actual problem is.
|
5

reversed and sorted do not sort in-place; instead they return the newly sorted and reversed object. Change the second to last line to

z = list(reversed(sorted(z, key=lambda x: x[1])))

and it will work. The list call is because reversed returns an iterator rather than a list (on Python3, at least).

It might be a bit less verbose to do the following

z = sorted(z, key=lambda x: x[1], reverse=True)

1 Comment

Hi, I get <listreverseiterator object at 0x7f8aa4524b90>
2

It's almost correct - if you check help(reversed) in a Python REPL you'll find that it returns an iterator containing your sorted result based on your dict's values.

If you want z to store your updated, reversed sorted list on count, you'll need to reassign z:

z = list(reversed(sorted(z, key=lambda x: x[1])))

Edit: just to clarify, the outermost list conversion of the iterator objects 'converts' the iterator into a list of the objects contained inside the iterator.

Comments

1

Least changes to your code:

s = "betty bought a bit of butter but the butter was bitter"
words = s.split()
l = []
k = []
unique_words = sorted(set(words))
for word in unique_words:
     k.append(word)
     l.append(words.count(word))

z = zip(k,l)
print z
z = sorted(z, key=lambda x: x[1] , reverse=True)
print z

sorted() does not sort in place and it has a built-in reverse option that you omitted.

Comments

1

To count the words in the string, you can simply use Counter from collections. Then sort it in the descending order of counts.

Your code can be shortened to

from collections import Counter
s = "betty bought a bit of butter but the butter was bitter"
c = Counter(i for i in s.split())
print sorted(c.items(),key=lambda x:x[1],reverse=True)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.