| Store | Cart

Suggesting a new feature - "Inverse Generators"

From: Bengt Richter <b...@oz.net>
Fri, 25 Mar 2005 22:11:20 GMT
On Fri, 25 Mar 2005 12:07:23 -0800, Michael Spencer <mahs at telcopartners.com> wrote:

>Scott David Daniels wrote:>> Michael Spencer wrote:>> >>> itertools.groupby enables you to do this, you just need to define a >>> suitable grouping function, that stores its state:>> >> >> Michael, this would make a great Python Cookbook Recipe.>> >OK, will do.  What would you call it?  Something like: "Stateful grouping of >iterable items">>[Bengt]:>> Nice, but I think "record" is a bit opaque semantically.>> How about group_id or generate_incrementing_unique_id_for_each_group_to_group_by or such?>> >> Regards,>> Bengt Richter>>Agreed, it's an issue.  I think the most natural name is groupby - but that >would cause more trouble.  What do you think about 'grouping' ?>I would use 'generate_incrementing_unique_id_for_each_group_to_group_by', but >then people might think I'm trying to outdo Bob Ippolito :-)>>[Serge]:>> I think your example would>> be more clear for Jordan if you used function attributes:>> >> def record(item):>>      if len(item) > 20:>>          record.seq +=1>>      return record.seq>> record.seq = 0>>That does read better than the mutable default argument hack.  Is this use of >function attributes generally encouraged? (I tend to think of func_dict for >meta-data, used only outside the function)  Thoughts?>
Personally, I don't like depending on an externally bound (and rebindable) (usually global)
name as a substitute for "self." You could always use a class to carry state, e.g. (untested)

    class Grouper(object):
        def __init__(self): self.group_id = 0
        def __call__(self, item):
            if len(item) > 20: self.group_id += 1 # advance id to next group
            return self.group_id
    # ...
    grouper = Grouper()
    # ...
    for groupnum, lines in groupby(linesource, grouper):
        print "".join(lines)

Or (guess I better actually try this one ;-)

 >>> linesource = """\
 ... Here is a long line, long line, long line
 ... and this is short
 ... and this is short
 ... Here is a long line, long line, long line
 ... and this is short""".splitlines()
 >>>>>> for groupnum, lines in groupby(linesource, type('',(),{'n':0, '__call__':lambda s,i: setattr(s,'n', s.n+(i>20)) or s.n})()):
 ...     print "".join(lines)
 ...
 Here is a long line, long line, long line
 and this is short
 and this is short
 Here is a long line, long line, long line
 and this is short

Regards,
Bengt Richter

Recent Messages in this Thread
Jordan Rastrick Mar 25, 2005 04:04 pm
Jordan Rastrick Mar 25, 2005 04:10 pm
Andrew Koenig Mar 25, 2005 04:18 pm
Jordan Rastrick Mar 25, 2005 04:36 pm
Andrew Koenig Mar 26, 2005 01:40 pm
Tim Hochberg Mar 25, 2005 04:25 pm
Michael Spencer Mar 25, 2005 04:46 pm
Jordan Rastrick Mar 25, 2005 05:23 pm
Michael Spencer Mar 25, 2005 06:41 pm
Serge Orlov Mar 25, 2005 07:14 pm
Jordan Rastrick Mar 26, 2005 06:56 am
Peter Otten Mar 26, 2005 08:04 am
Scott David Daniels Mar 25, 2005 07:34 pm
Michael Spencer Mar 25, 2005 08:07 pm
Scott David Daniels Mar 25, 2005 09:00 pm
Bengt Richter Mar 25, 2005 10:11 pm
Bengt Richter Mar 25, 2005 07:43 pm
Terry Reedy Mar 25, 2005 07:13 pm
Jordan Rastrick Mar 25, 2005 04:49 pm
Diez B. Roggisch Mar 25, 2005 06:13 pm
Jordan Rastrick Mar 26, 2005 04:11 pm
phil...@yahoo.com Mar 27, 2005 03:44 am
Oren Tirosh Mar 27, 2005 06:58 am
Messages in this thread