Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #87657 > unrolled thread

Brilliant or insane code?

Started byMark Lawrence <breamoreboy@yahoo.co.uk>
First post2015-03-18 00:35 +0000
Last post2015-03-18 15:20 +0000
Articles 6 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  Brilliant or insane code? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-03-18 00:35 +0000
    Re: Brilliant or insane code? Dan Sommers <dan@tombstonezero.net> - 2015-03-18 01:14 +0000
      Re: Brilliant or insane code? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-18 13:25 +1100
        Re: Brilliant or insane code? Dan Sommers <dan@tombstonezero.net> - 2015-03-18 03:06 +0000
      Re: Brilliant or insane code? Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-18 08:59 -0600
      Re: Brilliant or insane code? Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-03-18 15:20 +0000

#87657 — Brilliant or insane code?

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2015-03-18 00:35 +0000
SubjectBrilliant or insane code?
Message-ID<mailman.507.1426638964.21433.python-list@python.org>
I've just come across this 
http://www.stavros.io/posts/brilliant-or-insane-code/ as a result of 
this http://bugs.python.org/issue23695

Any and all opinions welcomed, I'm chickening out and sitting firmly on 
the fence.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

[toc] | [next] | [standalone]


#87661

FromDan Sommers <dan@tombstonezero.net>
Date2015-03-18 01:14 +0000
Message-ID<meajh1$hr0$2@dont-email.me>
In reply to#87657
On Wed, 18 Mar 2015 00:35:42 +0000, Mark Lawrence wrote:

> I've just come across this
> http://www.stavros.io/posts/brilliant-or-insane-code/ as a result of
> this http://bugs.python.org/issue23695
> 
> Any and all opinions welcomed, I'm chickening out and sitting firmly
> on the fence.

According to the article itself, "it relies in an implementation detail
(the order the zip function iterates over the arrays) to work."  Then
again, the article also points to the official docs that says that this
implementation detail is guaranteed.

So it's no worse than depending on some weird but *documented* corner of
the IEEE-754 or POSIX spec.

[toc] | [prev] | [next] | [standalone]


#87663

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-03-18 13:25 +1100
Message-ID<5508e22b$0$2760$c3e8da3$76491128@news.astraweb.com>
In reply to#87661
On Wednesday 18 March 2015 12:14, Dan Sommers wrote:

> On Wed, 18 Mar 2015 00:35:42 +0000, Mark Lawrence wrote:
> 
>> I've just come across this
>> http://www.stavros.io/posts/brilliant-or-insane-code/ as a result of
>> this http://bugs.python.org/issue23695
>> 
>> Any and all opinions welcomed, I'm chickening out and sitting firmly
>> on the fence.
> 
> According to the article itself, "it relies in an implementation detail
> (the order the zip function iterates over the arrays) to work."  Then
> again, the article also points to the official docs that says that this
> implementation detail is guaranteed.

That means it isn't an implementation detail, it's interface. Consider:

"This relies on an implementation detail that len() of a list returns the 
number of items of the list. P.S. the documentation guarantees that len() of 
a list will return the number of items of the list."


The technique being used neither brilliant nor insane. At most, it is a 
moderately clever way of grouping values. It's a Neat Trick that every 
Python programmer should learn.

py> data = list("abcdefghijklmno")
py> zip(*[iter(data)]*3)
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i'), ('j', 'k', 'l'), ('m', 
'n', 'o')]


How it works is simple. Create an iterator from your data sequence, then 
call zip with 3 arguments of *the same* iterator (not 3 separate iterators). 
Since zip() is guaranteed to call next(iterator) in left-to-right order, 
this is more or less the same as:

def group(data):
    it = iter(data)
    while True:
        accum = []
        for i in range(3):
            accum(next(it))
        yield tuple(accum)


modulo error handling. The syntax is a bit Perlish, but every part of the 
code is absolutely straight-forward and standard Python semantics:

zip(*[iter(data)]*3):


    iter(data)  # trivial, make an iterator from an iterable

    [iter(data)]  # put it in a list

    [iter(data)]*3  # list replication -- 3 references to the same iterator

    *[iter(data)]*3  # expand to three arguments

    zip(...)  # and zip 'em up from left to right




-- 
Steve

[toc] | [prev] | [next] | [standalone]


#87665

FromDan Sommers <dan@tombstonezero.net>
Date2015-03-18 03:06 +0000
Message-ID<meaq3t$sls$1@dont-email.me>
In reply to#87663
On Wed, 18 Mar 2015 13:25:45 +1100, Steven D'Aprano wrote:

> On Wednesday 18 March 2015 12:14, Dan Sommers wrote:

>> According to the article itself, "it relies in an implementation
>> detail (the order the zip function iterates over the arrays) to
>> work."  Then again, the article also points to the official docs that
>> says that this implementation detail is guaranteed.

> That means it isn't an implementation detail, it's interface ...

Agreed.  I only called it an implementation detail to preserve (or to
create) continuity.

> "This relies on an implementation detail that len() of a list returns
> the number of items of the list. P.S. the documentation guarantees
> that len() of a list will return the number of items of the list."

> The technique being used neither brilliant nor insane ...

Insightful?

Idiomatic?

Pythonic?

It's certainly fairly obvious once you've seen it.

[toc] | [prev] | [next] | [standalone]


#87683

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-03-18 08:59 -0600
Message-ID<mailman.3.1426690849.10327.python-list@python.org>
In reply to#87661
On Tue, Mar 17, 2015 at 7:14 PM, Dan Sommers <dan@tombstonezero.net> wrote:
> On Wed, 18 Mar 2015 00:35:42 +0000, Mark Lawrence wrote:
>
>> I've just come across this
>> http://www.stavros.io/posts/brilliant-or-insane-code/ as a result of
>> this http://bugs.python.org/issue23695
>>
>> Any and all opinions welcomed, I'm chickening out and sitting firmly
>> on the fence.
>
> According to the article itself, "it relies in an implementation detail
> (the order the zip function iterates over the arrays) to work."  Then
> again, the article also points to the official docs that says that this
> implementation detail is guaranteed.
>
> So it's no worse than depending on some weird but *documented* corner of
> the IEEE-754 or POSIX spec.

In fact, this is also a code recipe found in the itertools
documentation. The official docs don't just guarantee it; they
*recommend* it.

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)

https://docs.python.org/3.4/library/itertools.html

[toc] | [prev] | [next] | [standalone]


#87684

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2015-03-18 15:20 +0000
Message-ID<mailman.4.1426692040.10327.python-list@python.org>
In reply to#87661
On 18/03/2015 14:59, Ian Kelly wrote:
> On Tue, Mar 17, 2015 at 7:14 PM, Dan Sommers <dan@tombstonezero.net> wrote:
>> On Wed, 18 Mar 2015 00:35:42 +0000, Mark Lawrence wrote:
>>
>>> I've just come across this
>>> http://www.stavros.io/posts/brilliant-or-insane-code/ as a result of
>>> this http://bugs.python.org/issue23695
>>>
>>> Any and all opinions welcomed, I'm chickening out and sitting firmly
>>> on the fence.
>>
>> According to the article itself, "it relies in an implementation detail
>> (the order the zip function iterates over the arrays) to work."  Then
>> again, the article also points to the official docs that says that this
>> implementation detail is guaranteed.
>>
>> So it's no worse than depending on some weird but *documented* corner of
>> the IEEE-754 or POSIX spec.
>
> In fact, this is also a code recipe found in the itertools
> documentation. The official docs don't just guarantee it; they
> *recommend* it.
>
> 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)
>
> https://docs.python.org/3.4/library/itertools.html
>

Which is available here https://pypi.python.org/pypi/more-itertools 
along with many other goodies.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web