Live data from Hacker News

Counting Things in Python: A History

treyhunner.com

21–30 of 61 posts

Re: Counting Things in Python: A History

#21
post #17

The try block method would be considered bad in most languages, and I hope it is considered bad in Python as well. Using exception handling as part of a normal flow of control is bad style, bad taste, and bad for performance. EDIT: I'm glad to see the Python documentation addresses this: https://docs.python.org/2/faq/design.html#how-fast-are-excep...

It's not considered quite that bad. In many languages, using exceptions for non-exceptional flow control is bad style. Python is a bit more ambivalent about this, for instance take a look at the iterator protocol which uses an exception to signal the iterator is done. https://docs.python.org/2/library/stdtypes.html#iterator-typ...

That turned out to be not that great of an idea, and it's changed in Python 3.5: https://www.python.org/dev/peps/pep-0479/

Re: Counting Things in Python: A History

#22
post #17

Earlier quoted context omitted.

It's not considered quite that bad. In many languages, using exceptions for non-exceptional flow control is bad style. Python is a bit more ambivalent about this, for instance take a look at the iterator protocol which uses an exception to signal the iterator is done. https://docs.python.org/2/library/stdtypes.html#iterator-typ...

That turned out to be not that great of an idea, and it's changed in Python 3.5: https://www.python.org/dev/peps/pep-0479/

That's not a change to the iterator protocol. It's a change to 'StopIteration handling inside generators'.

The following will still raise a StopIteration in Python 3.5+:

    >>> next(iter([]))

Re: Counting Things in Python: A History

#23
post #22

Earlier quoted context omitted.

That turned out to be not that great of an idea, and it's changed in Python 3.5: https://www.python.org/dev/peps/pep-0479/

That's not a change to the iterator protocol. It's a change to 'StopIteration handling inside generators'. The following will still raise a StopIteration in Python 3.5+: >>> next(iter([]))

Yep, the fundamental termination mechanism seems to be the same. Years and years ago I got into some silly irc nerdgument with a python expert (I think one of the twisted people) about the ugliness of this design and for a moment I thought I got to triumphantly yell 'Told you so!' a decade later. Alas, not the case.

Re: Counting Things in Python: A History

#26
just for fun...

  import itertools
  colors = ["brown", "red", "green", "yellow", "yellow", "brown", "brown", "black"]
  dict([(color, len(list(grp))) for color, grp in itertools.groupby(sorted(colors))])
or

  dict([(color, len(filter(lambda c: c==color, colors))) for color in set(colors)])
...because sometimes job security is important too.

Re: Counting Things in Python: A History

#27

$ txr This is the TXR Lisp interactive listener of TXR 123. Use the :quit command or type Ctrl-D on empty line to exit. 1> [hash-update [group-by identity '(brown red green yellow yellow brown brown black)] length] #H(() (green 1) (red 1) (brown 3) (black 1) (yellow 2)) Form a hash by grouping like items into lists. The identity function is the key in the hash and the basis for equality, so the keys are colors, and t…

[deleted]

Re: Counting Things in Python: A History

#28

$ txr This is the TXR Lisp interactive listener of TXR 123. Use the :quit command or type Ctrl-D on empty line to exit. 1> [hash-update [group-by identity '(brown red green yellow yellow brown brown black)] length] #H(() (green 1) (red 1) (brown 3) (black 1) (yellow 2)) Form a hash by grouping like items into lists. The identity function is the key in the hash and the basis for equality, so the keys are colors, and t…

I guess this is off topic, but neat language. But that algorithm allocates a bunch of intermediate lists and iterates through the hash table when it doesn't need to. Here it is in common lisp: (defun count-elements (lst) (loop with rval = (make-hash-table) for val in lst do (incf (gethash val rval 0)) finally (return rval)))

It's better (by default) to optimize for programmer time and succinct expression unless something else takes priority, like running time, memory use, image size, etc.

The TXR version of the iterative approach:

  1> (let ((h (hash)))
       (each ((c '(brown red green yellow yellow brown brown black)))
         (inc [h c 0]))  ;; (inc (gethash c h 0)) can be used
       h)
  #H(() (black 1) (yellow 2) (green 1) (red 1) (brown 3))
Or:

  2> (let ((h (hash)))
       (mapdo (do inc [h @1 0])
              '(brown red green yellow yellow brown brown black))
       h)
  #H(() (black 1) (yellow 2) (green 1) (red 1) (brown 3))
I toyed with porting some loop macro implementation to TXR Lisp. I looked at some historic sources and just went "gack". Followed by, "what am I thinking".

I think in the end I would go for something like iterate, but even more Lispy. (Iterate still has "for x in y" type syntax in the clauses, just with parentheses around it; I would drop the infix "in" cruft and just have a symbol followed by nothing but semantic arguments)

Post reply on HN