On Tue, Aug 22, 2017 at 12:31 PM, Chris Barker <chris.bar...@noaa.gov> wrote: > Personally, I've thought for years that Python's "Truthiness" concept is a wart. > Sure, empty sequences, and zero values are often "False" in nature, > but truthiness really is application-dependent -- in particular, sometimes > a value of zero is meaningful, and sometimes not.
I think truthiness is easily a wart in any dynamically-typed language (and yet ironically, every language I can think of that has truthiness is dynamically typed except for C++). And yet for some reason it seems to be pressed forward as idiomatic in python, and for that reason alone, I use it. These are questions I ask myself on a daily basis, just to support this strange idiom: - How close to the public API is this argument? - Is '' a reasonable value for this string? - How about an empty tuple? Empty set? - Should this sentinel value be None or a new object()? - Is this list local to this function? - Is the type of this optional argument always True? - How liable are these answers to change with future refactoring? which seems like a pretty big laundry list to keep in check for what's supposed to be syntactic sugar. In the end, I will admit that I think my code "looks nice," but I think that's only because I've gotten used to seeing it! After answering all of these questions I tend to find that truthiness is seldom usable in any sort of generic code. These are the kinds of places where I usually find myself using truthiness instead, and all involve working with objects of known type: # 1. A list used as a stack while stack: top = stack.pop() ... def read_config(d): # 2. Empty default value for a mutable argument that I don't mutate d = dict(d or {}) a = d.pop('a') b = d.pop('b') ... # 3. Validating configuration if d: warn('unrecognized config keys: {!r}'.format(list(d))) # 4. Oddball cases, e.g. the "linked list" (a, (b, (c, (d, (e, None))))) def iter_linked_list(node): while node: value, node = node yield value # 5. ...more oddball stuff... def format_call(f, *args, **kw): arg_s = ', '.join(repr(x) for x in args) kw_s = ', '.join(f'{k:!s}={v:!r}' for k,v in kw.items()) sep = ', ' if args and kw else '' return f'{f.__name__}({arg_s}{sep}{kw_s})' Meanwhile, for an arbitrary iterator taken as an argument, if you want it to have at least one element for some reason, then good luck; truthiness will not help you.
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion