28
def sort_dictionary( wordDict ):
    sortedList = []
    for entry in sorted(wordDict.iteritems(), key = lambda (k, v): (-v, k) ):
        sortedList.append( entry )

    return sortedList

The function would be receiving a dictionary containing information such as:

{ 'this': 1, 'is': 1, 'a': 1, 'large': 2, 'sentence': 1 }

I would like to have it generate a list of lists, with the elements ordered first by the dictionary's values from largest to smallest, then by the keys alphabetically.

The function works fine when run with python 2.7.2, but I receive the error:

  File "frequency.py", line 87
    for entry in sorted(wordDict.iteritems(), key = lambda (k, v): (-v, k)):
                                                           ^
SyntaxError: invalid syntax

when I run the program with python 3.2.3.

I have been searching all over for a reason why, or syntax differences between 2.7 and 3.2, and have come up with nothing. Any help or fixes would be greatly appreciated.

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
Zack
  • 297
  • 1
  • 3
  • 9
  • 3
    It's worth noting that putting spaces between the `=` and an argument is against [PEP-8](http://www.python.org/dev/peps/pep-0008/#other-recommendations)'s recommendations. – Gareth Latty Mar 29 '13 at 22:16

1 Answers1

65

Using parentheses to unpack the arguments in a lambda is not allowed in Python3. See PEP 3113 for the reason why.

lambda (k, v): (-v, k)

Instead use:

lambda kv: (-kv[1], kv[0])
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • Why was this syntax removed? – Blender Mar 29 '13 at 22:14
  • 5
    @Blender It was shown to be little used, and made things like function annotations awkward, as well as adding complexity to some introspection stuff. It's also very easily replaced. See [PEP-3113](http://www.python.org/dev/peps/pep-3113/). – Gareth Latty Mar 29 '13 at 22:14
  • Thank you so much! this works perfectly. Also, not that it matters, but would you happen to know why I had to change iteritems() to items() to run it with python3 as well? – Zack Mar 29 '13 at 22:17
  • 2
    @Zack `iteritems()` was there as `items()` in 2.x returns a list, which is memory-inefficient. In 3.x, `items()` returns an iterator, removing the need for `iteritems()`. – Gareth Latty Mar 29 '13 at 22:18
  • Python really could use better syntax documentation for list comprehensions and lambdas. – AdamC Mar 09 '16 at 20:50
  • You could use the lambda with out paranthesis. lambda k, v: -v, k – Naren Babu R Aug 10 '20 at 05:55
  • 1
    @NarenBabuR That lambda would require two different arguments when called, not a single tuple. – MEMark Dec 21 '20 at 08:09