[Tutor] Python functions are first-class citizens

Ben Finney ben+python at benfinney.id.au
Fri Aug 1 10:33:33 CEST 2014


memilanuk <memilanuk at gmail.com> writes:

> On 07/31/2014 11:46 PM, Ben Finney wrote:
>
> > The ‘max’ function can be told how to determine the ordering of
> > items, by specifying a key parameter. The parameter is specified by
> > giving a value; that value is a function.
>
> Hmmm... might just have had a break-thru here: so max() iterates thru
> counts

No. You should not expect ‘max’ to iterate through anything. All it does
is compute, somehow, which item in the collection is largest. Iteration
isn't relevant to that.

I'm being a stickler on this point because “iterate” implies something
quite specific in Python, and this behaviour is not implied by the
purpose of ‘max’.

Instead, think only “finds the largest item in the collection”.

> which because its the only non-keyword argument provided has to be an
> iterable (if I'm reading this correctly:
> https://docs.python.org/3/library/functions.html?highlight=max#max).

You're reading that right. I consider that document a bit confusing,
though; I would prefer instead that it says “collection”, because
whether the collection is iterable shouldn't matter.

> It takes each dict key ('a', 'b', 'c')

Ah! Now I get a better idea why you're confused. There are two distinct
uses of “key” going on.

The dict has a key for each item, so called because the key is used to
access a specific item in the dict.

The ‘max’ operation needs a defined algorithm to determine which of two
items is larger. It calls this algorithm the “key function”, because
this is the same terminology used when sorting the collection. So ‘max’
takes an optional function as the “key function”, which is named ‘key’.

But those two uses are distinct, and the “key function” for determining
order in a sequence doesn't really relate to the key of a dict item.

The terminology in computing often has conflicting uses of the same
word; “key” is unfortunately one of those words.

> feeds them in turn to counts.get() like so: counts.get('a'),
> counts.get('b'), counts.get('c'), which should return the
> corresponding dict values (1, 22, 100), and then max() returns the
> highest value seen.
>
> Is that about right?

Roughly, except:

* Computing the largest item doesn't imply iteration at all, so it's
  misleading to think of “iterate” at all. The ‘max’ function has as its
  first argument a collection, whether that collection is iterable or
  not.

* There is no guarantee all the items will be seen. ‘max’ could very
  well decide it's got the largest item and return it at any point. It's
  an implementation detail how it does that.

* The “key function” expected by ‘max’ in its ‘key’ parameter has no
  real relation to the key of a dictionary item, except by coincidence
  here.

Broadly, you should consider the ‘max’ function a black box. (It's not,
though, and if you're *really* curious you can inspect the source code
of your particular Python implementation and see one possible way of
doing it — bearing in mind that there's no guarantee it will be
implemented the same way anywhere else.)

When you call the ‘max’ function, don't think of it doing any specific
sequence of steps. You specify a collection of items; you may specify a
key function to be used for determining which of two items is the
larger. The result is that ‘max’ uses the specified key function to
compute the largest item from the specified collection, and returns that
item.

-- 
 \          “Those who write software only for pay should go hurt some |
  `\                 other field.” —Erik Naggum, in _gnu.misc.discuss_ |
_o__)                                                                  |
Ben Finney



More information about the Tutor mailing list