Live data from Hacker News

Counting Things in Python: A History

treyhunner.com

41–50 of 61 posts

Re: Counting Things in Python: A History

#41

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.

Or this (not efficient but fun, and using a dict comprehension and no itertools):

    {a: sum(a == b for b in colors) for a in set(colors)}

Re: Counting Things in Python: A History

#43

This makes me appreciate autovivification and casting in perl so that you can just say "$color_counts{$color} += 1" without all the initialization.

So how do I know if "1" gets added to a 0 or to an empty string?

I suppose there's some type inference there and you'll get the default be 0 since 1 is also an integer, not a string.

Re: Counting Things in Python: A History

#44
post #32

The author seems to misunderstand one part of The Zen of Python: | Simple is better than complex. by saying: > Our code is more complex (O(n2) instead of O(n)), less beautiful, and less readable The Zen is not about computation complexity! It's about complexity of the source code. The code in question is: color_counts = dict((c, colors.count(c)) for c in set(colors)) And while I agree that this is inefficient and sho…

[deleted]

Re: Counting Things in Python: A History

#46

$ 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)))

[deleted]

Re: Counting Things in Python: A History

#47
post #38
post #32

The author seems to misunderstand one part of The Zen of Python: | Simple is better than complex. by saying: > Our code is more complex (O(n2) instead of O(n)), less beautiful, and less readable The Zen is not about computation complexity! It's about complexity of the source code. The code in question is: color_counts = dict((c, colors.count(c)) for c in set(colors)) And while I agree that this is inefficient and sho…

I don't think you should get into the habit of writing O(n^2) algorithms if the O(n) solution is not much more complex. Unless the constants are very dissimilar, you probably hurt your performance already for a few hundred elements. Writing reusable code includes using algorithms that are ok for a wide range of input sizes.

[deleted]

Re: Counting Things in Python: A History

#48
post #20
post #7

Earlier quoted context omitted.

Exceptions in python have historically been very cheap.

That's not true. There was a paper at the 1997 Python conference on this topic titled "Standard Class Exceptions in Python". A copy is at https://web.archive.org/web/20030610173145/http://barry.wars... . It evaluated the performance of try/except vs. has_key and concluded: > This indicates that the has_key() idiom is usually the best one to choose, both because it is usually faster than the exception idiom, and becau…

Interesting. My information was not only out of date; it was also wrong. The dangers of cargo-culting, although in my case, more theoretical than real, as I never had performance-sensitive python code in production.

Re: Counting Things in Python: A History

#49
post #36
post #34

Earlier quoted context omitted.

Yes! This was one of the biggest things I missed when I moved to Ruby. I try and tell people how great autovivification is but unless they've coded with it the feature just sounds strange. But it lets you build some really great data structures on the fly!

I love it as well, and would hate to do without it, but it does come with it's own warts. Such as this: use Data::Dumper; my %h; if ( $h{foo}{bar}{baz} ) { say "Never happens"; } say Dumper \%h; And you get this: $VAR1 = { 'foo' => { 'bar' => {} } };

You'd want to use the exists operator in that case. It checks if the hash key is present without auto vivifying it.

  my %hash = ();
  if (exists $hash{foo}) {print "This doesn't run!";}

Re: Counting Things in Python: A History

#50

This makes me appreciate autovivification and casting in perl so that you can just say "$color_counts{$color} += 1" without all the initialization.

So how do I know if "1" gets added to a 0 or to an empty string?

Perl uses separate operators for mathematical addition and string concatenation.

  1 + 1 == 2;
  1 . 1 eq 11;
It uses separate operators for most mathematical and string operations, for that matter. There isn't much of a meaningful difference between strings and numbers in Perl -- it converts between then depending on the operation.
Post reply on HN