[Python-3000] genexp syntax for reduce (already in 2.5a1)
Guido van Rossum
guido at python.org
Tue Apr 18 20:38:21 CEST 2006
I wouldn't recommend this approach to anyone.
On 4/18/06, Boris Borcic <boris at batiment71.net> wrote:
> Hello,
>
> Since the notion of a "generator comprehension" reduce syntax for py3k was
> discussed on this list - it may have escaped attention that py2.5a1 already
> allows the following, admittedly not very efficient (nor too robust in this
> proof-of-concept implementation).
>
> hth, Boris Borcic
>
>
> def ireduce(gen) :
> """
> Generator expression syntax for reduce and generalizations
>
> Usage examples:
>
> - (yield) nothing as below if there is no seed value
> *and* the expression consists of a single arithmetic op
>
> >>> ireduce(x+(yield) for x in range(101)) # famous Gauss example
> 5050
> >>> ireduce(x*(yield) for x in range(1,6))
> 120
>
> - if there is a seed, yield it (unless it's None)
>
> >>> ireduce(x*(yield 2) for x in range(1,6)) # 2*1*2*3*4*5
> 240
> >>> ireduce(x*(yield 2) for x in range(2,6)) # 2*2*3*4*5
> 240
> >>> ireduce(x*(yield 2) for x in range(6)) # 2*0*1*2*3*4*5
> 0
>
> - if the seed is None, (yield INone) instead
>
> >>> ireduce((x,(yield INone)) for x in "for all good men".split())
> ('men', ('good', ('all', ('for', None))))
>
> >>> ireduce([(yield INone),x] for x in "for all good men".split())
> [[[[None, 'for'], 'all'], 'good'], 'men']
>
> - do as below if you want no special seed and the operation to reduce
> isn't a simple arithmetic operation
>
> >>> ireduce((x,(yield Seed(x))) for x in "for all good men".split())
> ('men', ('good', ('all', 'for')))
>
> >>> ireduce(x+' '+(yield Seed(x)) for x in "for all good men".split())
> 'men good all for'
>
> >>> ireduce({ x : (yield Seed(x))} for x in "for all good men".split())
> {'men': {'good': {'all': 'for'}}}
>
> - and notice these for a comparison
>
> >>> ireduce({ x : (yield x)} for x in "for all good men".split())
> {'men': {'good': {'all': {'for': 'for'}}}}
>
> >>> ireduce({ x : (yield Seed(None))} for x in "for all good men".split())
> {'men': {'good': {'all': None}}}
> """
>
> cumulate = gen.next()
> if cumulate is None :
> cumulate = Neutral()
> elif cumulate is INone :
> cumulate = None
> elif isinstance(cumulate,Seed) :
> cumulate = cumulate.seed
> gen.send(cumulate)
> gen.next()
> try :
> while True :
> cumulate = gen.send(cumulate)
> gen.next()
> except StopIteration :
> return cumulate
>
> class Neutral : # this would need reworking
> def __coerce__(self,other) :
> self.other = other
> return (self,self)
>
> def __getattr__(self,attr) :
> return lambda *x,**y : self.__dict__['other']
>
> class INone : pass
>
> class Seed :
> def __init__(self,seed) :
> self.seed = seed
>
>
> _______________________________________________
> Python-3000 mailing list
> Python-3000 at python.org
> http://mail.python.org/mailman/listinfo/python-3000
> Unsubscribe: http://mail.python.org/mailman/options/python-3000/guido%40python.org
>
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-3000
mailing list