4

My program is given a source of data with "value" and "number of occurrences" columns, as a collection of tuples (value, frequency). In Python 2.6 or 2.7, I'd do this:

ls.sort(key=lambda (value, frequency): -frequency)

But Python 3 removed the ability to unpack a tuple parameter. It doesn't hurt quite as much in named functions because one can unpack with an assignment statement in the body of a function (Nested arguments in python not compiling). But because a lambda body cannot use assignment statements, one can't unpack in this way (Python lambda does not accept tuple argument).

PEP 3113 recommends this workaround:

ls.sort(key=lambda row: -row[1])

But this use of 1 as a magic number leaves a bad taste in my mouth. Is the use of such magic numbers idiomatic in Python 3? Or should I create a named function for each case where I had previously used tuple unpacking in a lambda, like this?

def negative_of_frequency_from_value_frequency_tuple(value_freq):
    value, freq = value_freq
    return -freq

ls.sort(key=negative_of_frequency_from_value_frequency_tuple)

Or should I bug the author of the library that provides these tuples to return named tuples instead of plain tuples?

Community
  • 1
  • 1
Damian Yerrick
  • 4,602
  • 2
  • 26
  • 64
  • To avoid the magic number, you could do e.g. `VALUE_INDEX, FREQ_INDEX = range(2)`. – jonrsharpe Mar 15 '15 at 14:44
  • The use of magic numbers as indexes are fine; if you really don't want an index that could be arbitrarily in the middle use `-row[-1]` which would indicate the last index absolutely. –  Mar 15 '15 at 15:11
  • To me (and to code checker programs), unused local names are a code smell. I would use what you call a workaround, `lambda r: -r[1]`, even in 2.x. – Terry Jan Reedy Mar 16 '15 at 07:33

1 Answers1

1

If you need only a single level destructuring, you can get the same effect with a wrapper.

ls.sort(key=lambda x: (lambda value, frequency: frequency)(*x))

If you need multiple levels, then use the comprehensions

ls.sort(key=lambda x: next(-frequency for value, frequency in [x]))
Rahul Gopinath
  • 808
  • 10
  • 24