On Tue, May 26, 2020 at 10:14 PM David Mertz <mertz@gnosis.cx> wrote:
All of those uses, including those where you say otherwise, treat None as a sentinel. In the iter() case, the optional seconds argument is *called* 'sentinel'. Guido recently mentioned that he had forgotten the two argument form of iter(), which is indeed funny... But useful.
The second argument uses *any arbitrary value* as a sentinel. For instance: print("Type commands, or quit to end:") for cmd in iter(input, "quit"): do_stuff(cmd) There is nothing whatsoever about None here. It will call the function until it returns the sentinel. And this is completely different from the one-arg form of iter, so you can't use None as a default.
Well, ok functions.reduce() really does make it's own sentinel in order to show NONE as a "plain value". So I'll grant that one case is slightly helped by a hypothetical 'undef'.
Same again: reduce behaves as if the initial is prepended onto the sequence, and it has to treat None the same as any other value. But it would have to treat 'undef' as a value too, if it is indeed a value.
The NumPy, deque, and lru_cache cases are all ones where None is a perfect sentinel and the hypothetical 'undef' syntax would have zero value.
Yes, and I know a lot of languages in which lru_cache would use -1 as its sentinel. Granted.
I was wondering if anyone would mention Pandas, which is great, but in many ways and abuse of Pythonic programming. There None in an initializing collection (often) gets converted to NaN, both of which mean "missing", which is something different. This is kind of an abuse of both None and NaN... which they know, and introduced an experimental pd.NA for exactly that reason... Unfortunately, so far, actually using of.NA is cumbersome, but hopefully that gets better next version.
Within actual Pandas and function parameters, None is always a sentinel.
Definitely not always. Often, yes, but most definitely not always. ChrisA