[TriZPUG] iterate over a list in bunches
Kurt Grandis
KGrandis at lexile.com
Thu Aug 11 14:51:51 CEST 2011
If you prefer the itertools route you can make use of a pattern described on the itertools doc page called 'grouper'.
import itertools
class GroupIter(object):
def __init__(self, data, group_size=4, fill=None):
self._data = data
self._group_size = group_size
self._fill = fill
def __iter__(self):
#checkout itertools for related functions
groups = itertools.izip_longest(fillvalue=self._fill,
*[iter(self._data)]*self._group_size)
for group in groups:
# if you prefer truncation to fill, uncomment next line
group = [g for g in group if g is not None]
yield group
data = range(1, 34)
obj = GroupIter(data, 4)
print "data: %s, count: %s" % (data, len(data))
for ix,row in enumerate(obj):
print "Row: #%d" % (ix)
for field in row:
print "%s " % (field,),
print "\n---------------------------"
-----Original Message-----
From: trizpug-bounces+kgrandis=lexile.com at python.org [mailto:trizpug-bounces+kgrandis=lexile.com at python.org] On Behalf Of Josh Johnson
Sent: Wednesday, August 10, 2011 3:16 PM
To: trizpug at python.org
Subject: Re: [TriZPUG] iterate over a list in bunches
Some updates (thanks bac!):
import math
class testiter(object):
_row = 0
_rowcount = 4
_data = range(1, 34)
_counter = 0
@property
def rows(self):
return int(math.ceil(len(self._data)/float(self._rowcount)))
@property
def row(self):
return self._counter/self._rowcount
def __iter__(self):
"""
Returns one row of fields at a time
"""
start = self._counter
end = start+self._rowcount
row = self._data[start:end]
self._counter = end
for field in row:
yield field
if len(row) < self._rowcount:
raise StopIteration
obj = testiter()
print "data: %s, count: %s, rows: %s" % (obj._data, len(obj._data),
obj.rows)
for x in range(0, obj.rows+1):
print "Row: #%s" % (obj.row)
for field in obj:
print "%s " % (field,),
print "\n---------------------------"
Now it keeps track of the row number with some math, and avoids
unnecessarily performing multiplication when addition will suffice. I've
also added a StopIteration exception when we're on the last row, I'm not
sure if that's actually doing anything useful.
JJ
On 8/10/2011 12:40 PM, Josh Johnson wrote:
> Hi all,
> I had a use case where I had to iterate over a linear list of objects
> in bunches, for display in a tabular layout[1], this is how I
> implemented it, I'm interested in feedback on the approach:
>
> import math
>
> class testiter(object):
> _row = 0
> _rowcount = 4
> _data = range(1, 34)
>
> @property
> def rows(self):
> return int(math.ceil(len(self._data)/float(self._rowcount)))
>
> def __iter__(self):
> """
> Returns one row of fields at a time
> """
> start = self._row*self._rowcount
> end = start+self._rowcount
>
> row = self._data[start:end]
>
> self._row += 1
> for field in row:
> yield field
>
>
>
> obj = testiter()
> print "data: %s, count: %s, rows: %s" % (obj._data, len(obj._data),
> obj.rows)
> for x in range(0, obj.rows+1):
> for field in obj:
> print "%s " % (field,),
> print "\n---------------------------"
>
> Running this through python (tested with 2.6.6), yields this output
> (the dump of the data in the first line truncated a bit for brevity):
>
> data: [1, ... 33], count: 33, rows: 9
> 1 2 3 4
> ---------------------------
> 5 6 7 8
> ---------------------------
> 9 10 11 12
> ---------------------------
> 13 14 15 16
> ---------------------------
> 17 18 19 20
> ---------------------------
> 21 22 23 24
> ---------------------------
> 25 26 27 28
> ---------------------------
> 29 30 31 32
> ---------------------------
> 33
> ---------------------------
>
> ---------------------------
>
> Critiques?
>
> Thanks,
> JJ
>
> [1] For the record, it was displaying a list of dyanically-generated
> form fields from a Django ModelForm in a template. I was able to just
> call {% for field in form %} multiple times for each row.
>
--
Josh Johnson
Applications Analyst
Translational Pathology Laboratory
Lineberger Comprehensive Cancer Center
University of North Carolina at Chapel Hill
(919) 923-0894
_______________________________________________
TriZPUG mailing list
TriZPUG at python.org
http://mail.python.org/mailman/listinfo/trizpug
http://trizpug.org is the Triangle Zope and Python Users Group
More information about the TriZPUG
mailing list