Hacker News new | ask | show | jobs
by tlocke 1034 days ago
Someone else has mentioned it, but I would have gone with:

  sum(1 for age in ages if age > 17)
with the other method you're treating a boolean as an int. Weak typing.
3 comments

bool is explicitly documented to be a subclass of int [1][2], so while it might be an obscure feature, or subjectively not someone's preferred style, I don't see any typing related issue. In general I don't think that treating an object as if it were an instance of one of its base classes is weak typing.

[1]: https://docs.python.org/3/library/functions.html?highlight=s...

[2]: https://docs.python.org/3/library/stdtypes.html#boolean-valu...

I'd argue that even though it's well defined behaviour in Python, it still appears to me as a programmer as weak typing. For example, Python lets me write:

  if 23:
      print('hello')
and it'll print 'hello'. But I'd prefer a strongly typed approach where this code would give an error saying, 'a bool is expected here'. Sure it's a subjective thing, and this is just my preference.
Its not weak typeing, bools are ints.

“I don’t know the type hierarchy used in language X” is not the same thing as “language X is weakly typed”.

  Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit 
  (AMD64)] on win32
  Type "help", "copyright", "credits" or "license" for more information.
  >>> isinstance(True, int)
  True
  >>> isinstance(False, int)
  True
  >>> issubclass(bool, int)
  True
Bools are ints, but I'd say that makes Python weakly typed (ish - it's a spectrum obviously). Are you just using "weak typing" to mean "implicit type coercion"?
I agree with the improvement in readability but still like the bool/int equivalence:

    sum(int(age > 17) for age in ages)
Every nanosecond is vital!
Interesting, so I did a little test:

  python -m timeit 'sum(1 for age in range(100000) if age > 17)'
  50 loops, best of 5: 5.08 msec per loop

  python -m timeit 'sum(int(age > 17) for age in range(100000))'
  50 loops, best of 5: 7.96 msec per loop

  python -m timeit 'sum(age > 17 for age in range(100000))'
  50 loops, best of 5: 4.78 msec per loop
Yep, in python function calls are not cheap, you’re usually better off avoiding them in tight loops.

Plus here on each iteration `int` has to be loaded from the globals before it can be called.