On Fri, 25 Mar 2005 12:07:23 -0800, Michael Spencer <[EMAIL PROTECTED]> 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 -- http://mail.python.org/mailman/listinfo/python-list