Live data from Hacker News

Brilliant or insane code?

stavros.io

71–80 of 114 posts

Re: Brilliant or insane code?

#71

Earlier quoted context omitted.

It's using a somewhat-obscure guarantee that doesn't come up in normal usage of the function - namely, that it will always get the iterator values in left-right order.

it depends on the kind of code you write. i guess if you're writing web server stuff, documenting this makes sense. but in maths-related code, it's pretty standard. you use something very similar to transpose matrices, for example. (and the original article is dealing with coords in graphics, which is "maths-related code" in my book, but perhaps not in everyone's)

The original source is taken from a medical image DICOM viewer. In my limited experience as a medical physics student, the people working with these tools would really benefit from a comment explaining the code. They are most definitely not coders, most of them having barely done anything more than write a few matlab scripts.

Re: Brilliant or insane code?

#72
I wouldn't call it insane, neither brilliant. I use this function to split a sequence into pairs (or triplets, or fourths, etc):

  def paired(t, size=2, default=None):
    it = iter(t)
    return itertools.izip_longest(*[it]*size, fillvalue=default)
I use it in a formatter which outputs alphabetized data in columns, where the order should run down the columns instead rowwise.

Re: Brilliant or insane code?

#73
post #66

Earlier quoted context omitted.

The numpy example becomes fast when you use numpy arrays. Try %timeit numpy.array(arr); numpy.reshape(arr, (-1, 3)); and then just %timeit numpy.array(arr), you'll see that the reshape takes no time at all. Type conversion from python list to numpy array is what kills the performance.

A point of clarification here - numpy's reshape operation stays fast as long as the array is a numpy array. Which is exactly what the parent comment was all about - the author figured that the reason numpy was significantly faster was because it was accessing / working with the data in a different fashion. So, in order to test that theory, he converted the numpy.array into a normal python array before he proceeded to…

My reply was in response to the statement "numpy is two orders of magnitude faster here; it's evidently using a highly optimized internal codepath for random sequence generation", which is false, it's not because of highly optimized internal codepaths for random sequence generation, it's because the code produced a numpy array (or didn't have to do type conversion). But I agree, when using numpy to produce a timing comparison, it would be fair to start with a numpy array, or to show the time involved in the creation of the array.

Re: Brilliant or insane code?

#74
post #59

From Itertools Recipes [6]: def grouper(iterable, n, fillvalue=None): "Collect data into fixed-length chunks or blocks" # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return zip_longest(*args, fillvalue=fillvalue) - What is the most “pythonic” way to iterate over a list in chunks? [1] - Idiomatic way to take groups of n items from a list in Python? [2] - Python “Every Other Element” Idiom […

Figured I would add my own [7]. I know the example prompt might seem a bit specific, but it can come in really handy sometimes (for example, iterating through get parameters). Always a fan of idiomatic and one-liner python.

I should mention that I ended up using the fourth version (seemingly the slowest) but it is actually the fastest depending on your input -- as the length of the elements gets larger, the fourth method tends to vastly outperform the others.

[7] http://stackoverflow.com/questions/16685545/elegantly-iterat...

Re: Brilliant or insane code?

#75
If it's actually faster, the speed actually matters, and you wrap it with a well commented explanation and descriptive name, I'd consider it reasonable. Otherwise, just write out what you're doing. It's definitely clever, but fewer lines of code is not an optimization.

Re: Brilliant or insane code?

#76
post #17

This is in the zip documentation as the way of solving this problem. Sort of surprised the author didn't look up the documentation before writing what is otherwise a very good post. The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using zip(*[iter(s)]*n). http://docs.python.org/2/library/functions.html#zip

Recently I was downvoted 2-3 times on S.O. for an answer that was claimed to be non-idiomatic. So, I cleaned it up, but it really irked me. What I had written was totally fine. It shouldn't have hurt anyone's eyes. It was direct. It was in-your-face. It was not magic. Reading this post brought back that feeling. If people don't understand a completely valid and terse way of coding something, sometimes instead of both…

I think the mentality can be extended to most code-reading. Don't get it by skimming? Must be crap code. I only got away from that when I changed my litmus test towards whether I could write on top of the codebase successfully, not how it looked. Today my only real point of judgment about the look of code is whether it's written in a style that increases average error rate.

w/r to Python in particular, it has a history of ending up with idioms that are "tricky" and not particularly more or less terse than other techniques, but are able to exploit the standard library functions to get a faster-running result.

This is, of course, at odds with the motto of "there should be only one (obvious) way to do it," so every experienced Python programmer has to internalize a small dictionary of idiomatic one-liners for these exceptional cases. (Fortunately, it's not that big. I can only think of three or four off the top of my head.)

Re: Brilliant or insane code?

#77
post #51
post #17

This is in the zip documentation as the way of solving this problem. Sort of surprised the author didn't look up the documentation before writing what is otherwise a very good post. The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using zip(*[iter(s)]*n). http://docs.python.org/2/library/functions.html#zip

By the way, I was recently surprised by a similar pattern in linux, where you can do: (echo -e "one\ntwo\nthree\nfour") | paste -d, - - to get result of: one,two three,four by exploiting a similar trick, i.e. reading two times ('- -') from the same iterator (STDIN of 'paste')

Thanks for posting this. For reference, paste is a standard UNIX utility, whose purpose is to do all sorts of useful things not limited to 2-tuples:

  $ seq 1 9 | paste - - -
  1	2	3
  4	5	6
  7	8	9

Re: Brilliant or insane code?

#78
post #69

Earlier quoted context omitted.

I think that dependency on argument evaluation order inside zip function smells a bit. It's OK here, but may bite you with a different function.

The left-to-right evaluation order of the iterables is guaranteed. http://docs.python.org/2/library/functions.html#zip

Yes, but only for zip, which I believe was the parent posters point. With another function this technique might not work.

Re: Brilliant or insane code?

#80
post #17

This is in the zip documentation as the way of solving this problem. Sort of surprised the author didn't look up the documentation before writing what is otherwise a very good post. The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using zip(*[iter(s)]*n). http://docs.python.org/2/library/functions.html#zip

Kind of ironic for a language whose motto is "explicit is better".
Post reply on HN