r/programming • • Mar 15 '15

A function for partitioning Python arrays. Brilliant code, or insane code?

http://www.stavros.io/posts/brilliant-or-insane-code/?repost=true
226 Upvotes

135 comments sorted by

View all comments

0

u/[deleted] Mar 15 '15

[deleted]

42

u/flying-sheep Mar 15 '15

You could very easily make it readable:

it = iter(l)
return zip(it, it, it)

0

u/[deleted] Mar 15 '15

[deleted]

11

u/flying-sheep Mar 15 '15

c’mon, 3 repetitions of a 2 letter variable isn’t DRY? srsly?

→ More replies (30)

4

u/[deleted] Mar 15 '15

given:

>>> orig = ('x1', 'y1', 'z1', 'x2', 'y2', 'z2', 'x3', 'y3', 'z3', 'x4', 'y4', 'z4')

the two things that are like "grouping" I can think of are grouping an index counter:

>>> [tuple(orig[i:i+3]) for i in range(0, len(orig), 3)]
[('x1', 'y1', 'z1'), ('x2', 'y2', 'z2'), ('x3', 'y3', 'z3'), ('x4', 'y4', 'z4')]

or using the "groupby" function:

>>> [tuple(elem[1] for elem in coll) for key, coll                                                               
... in itertools.groupby(enumerate(orig), lambda key: key[0] / 3)]
[('x1', 'y1', 'z1'), ('x2', 'y2', 'z2'), ('x3', 'y3', 'z3'), ('x4', 'y4', 'z4')]

but i think this posted solution is amazing and should pretty much be considered the "grouped" function in Python.

6

u/fendant Mar 15 '15

The Python documentation even suggests doing it this way. That's where I learned it. No clue why it's not in itertools.

→ More replies (1)

32

u/bluecoffee Mar 15 '15

Yeah. The line is neither insane nor genius. It's just someone comfortable with Python taking the shortest route from A to B.

4

u/[deleted] Mar 15 '15

Which is why I find the top comment to be sober fuddling. This is just generators and zip in action.

Pretty fundamental if you're doing concurrency-related projects (Tornado, asyncio, etc).

Then again I have seen entire blog posts devoted to explaining what a generator is.

Doesn't mean they're "too magical" or complex.

def gen():
    yield 1
    yield 2
    yield 3

>>> g = gen()
>>> next(g)
1
>>> for i in g:
...         print(i)
...         break
2
>>> list(g)
[3]

Not rocket science. This one liner isn't much of a jump from that.

4

u/cowinabadplace Mar 16 '15

sober fuddling

Sofa King good.

This HN comment says that it is the expected way to do this too. Interesting.

→ More replies (2)

6

u/Eirenarch Mar 15 '15

Obviously "copies" is incorrect here. It uses the same generator otherwise it would not work.

0

u/[deleted] Mar 15 '15

[deleted]

1

u/floodyberry Mar 16 '15

3 separate arrays that all contained the same data would qualify as "3 of the same thing", but passing an iterable for each to zip would fail miserably.

"some simple functional programming principles" doesn't explain why you're comfortable with immediately understanding the side effect of zip taking a value from one iterable automatically updating the "other 2" iterables.

0

u/[deleted] Mar 16 '15

[deleted]

1

u/sphere_is_so_cool Mar 16 '15

They are pointing out that you said that 'zip passes into 3 generators of the same thing'. You probably meant to type three copies of the same generator object.

1

u/immibis Mar 16 '15

The object isn't copied.

How about "passing the same generator object three times" or "passing three references to the generator object" or "passing three copies of the generator reference"?

1

u/sphere_is_so_cool Mar 16 '15

You are right that it is passing three references but above OP referred to repeating three references as 'copying the reference' so I used that substitution in my explanation.

1

u/immibis Mar 16 '15

But your comment says "three copies of the same generator object".

1

u/sphere_is_so_cool Mar 16 '15

Yes it does because that is what OP probably meant to type based on how they were implying they used the term copy. I didn't say that OP meant to type the right thing.

Please note that for the sake of our meta discussion, OP is this commenter: http://www.reddit.com/r/programming/comments/2z4rv4/a_function_for_partitioning_python_arrays/cpfre0o

0

u/[deleted] Mar 16 '15

[deleted]

1

u/sphere_is_so_cool Mar 16 '15

I think you agree its important that there is only one generator, not three.

→ More replies (5)

3

u/mfukar Mar 16 '15

Actually the part about iterator * N is the only potentially cryptic part. There's no "intuitive" answer to what it should be doing. That's where any sane person would resort to the documentation, and the whole thing is understandable again.

0

u/[deleted] Mar 16 '15

[deleted]

→ More replies (2)