Nested lists or conditional logic?

M

mike beck

this is not all complex, but as a noob i'm having a hard time getting
my head around it.

i have a list of items. i need to print the items in batches of x,
with a summary line after each complete or partial batch, and a total
line at the end of the job.

if the list looks like ['line1','line2','line3'], and my ITEMSINBATCH
= 1, the output should look like this:

line1
---summary line---
line2
---summary line---
line3
---summary line---
---total line---

if ITEMSINBATCH = 2, the output should look like this:

line1
line2
---summary line---
line3
---summary line---
---total line---

i've done the following, which works, but it seems like there must be
a better/simpler/faster way to do this with nested loops. ideas?


# ---------------------Begin code---------------------
ITEMSINBATCH = 1;
ARBITRARYNUM = 51;

# create a list to work with
myList = ['1']*ARBITRARYNUM;

for i in range( len(myList) ):
# avoid starting at 0
count = i + 1;

print "The item is:",myList,'\t',count;

# ensure that the batch summary line is printed every ITEMSINBATCH
# times but not if the number of items is evenly divisible by
# ITEMSINBATCH, in which case both the inner print and the outer
# print would execute and we'd get consecutive batch summary lines
if ( (count) % ITEMSINBATCH ) is 0 and count != len(myList)::
print "-----Add batch summary line-----";

# add a final batch line for those trailing items
print "------Add batch summary line------And BTW, i is", count;

# and add the final summary line
print "------Add file summary------";

# ---------------------End code---------------------

TIA,
mike
 
J

Joe Francia

mike said:
> this is not all complex, but as a noob i'm having a hard time getting
> my head around it.
>
> i have a list of items. i need to print the items in batches of x,
> with a summary line after each complete or partial batch, and a total
> line at the end of the job.
>
> if the list looks like ['line1','line2','line3'], and my ITEMSINBATCH
> = 1, the output should look like this:
>
> line1
> ---summary line---
> line2
> ---summary line---
> line3
> ---summary line---
> ---total line---
>
> if ITEMSINBATCH = 2, the output should look like this:
>
> line1
> line2
> ---summary line---
> line3
> ---summary line---
> ---total line---
>
> i've done the following, which works, but it seems like there must be
> a better/simpler/faster way to do this with nested loops. ideas?
>
>
> # ---------------------Begin code---------------------
> ITEMSINBATCH = 1;
> ARBITRARYNUM = 51;
>
> # create a list to work with
> myList = ['1']*ARBITRARYNUM;
>
> for i in range( len(myList) ):
> # avoid starting at 0
> count = i + 1;
>
> print "The item is:",myList,'\t',count;
>
> # ensure that the batch summary line is printed every ITEMSINBATCH
> # times but not if the number of items is evenly divisible by
> # ITEMSINBATCH, in which case both the inner print and the outer
> # print would execute and we'd get consecutive batch summary lines
> if ( (count) % ITEMSINBATCH ) is 0 and count != len(myList)::
> print "-----Add batch summary line-----";
>
> # add a final batch line for those trailing items
> print "------Add batch summary line------And BTW, i is", count;
>
> # and add the final summary line
> print "------Add file summary------";
>
> # ---------------------End code---------------------



I'm not sure this is faster, but it sure is simpler:

mylist = range(23)
batchsize = 4

for i in range(0,len(mylist),batchsize):
for l in mylist[i:i+batchsize]:
print l
print "---summary line---"
print "---file summary---"
 
P

Peter Otten

mike said:
this is not all complex, but as a noob i'm having a hard time getting
my head around it.

i have a list of items. i need to print the items in batches of x,
with a summary line after each complete or partial batch, and a total
line at the end of the job.
[...]

i've done the following, which works, but it seems like there must be
a better/simpler/faster way to do this with nested loops. ideas?

Your code looks OK to me (apart from the duplicate colon). Here's a "no
maths" variant that uses nested loops:

from itertools import islice

ITEMSINBATCH = 3;
ARBITRARYNUM = 11;

sample = ["item #%d" % i for i in range(ARBITRARYNUM)]
it = iter(sample)

while True:
more = False
for item in islice(it, ITEMSINBATCH):
more = True
print item
if not more: break
print "summary"

I'm generally fond of the itertools module; this time I didn't find a way to
get rid of the ugly more flag, though. Implementing your own iterator with
a hasMore() method seems overkill.

Peter
 
T

Terry Reedy

mike beck said:
this is not all complex, but as a noob i'm having a hard time getting
my head around it.

i have a list of items. i need to print the items in batches of x,
with a summary line after each complete or partial batch, and a total
line at the end of the job.
i've done the following, which works, but it seems like there must be
a better/simpler/faster way to do this with nested loops. ideas?

The awkwardness is inherent in having non-0 remainders. An explicit
counter strikes me as both simple and fast. Maybe because what you did is
exactly the way I have done similar things. But I would probably make
print_summary a function to avoid duplicating code in two places.

Terry J. Reedy
 
P

Peter Otten

Here's another odd one:

from itertools import islice

ITEMSINBATCH = 3;
ARBITRARYNUM = 11;

sample = ["item #%d" % i for i in range(ARBITRARYNUM)]

def batches(s, n):
it = iter(s)
n -= 1
def batch(next):
yield next
for item in islice(it, n):
yield item
while True:
yield batch(it.next())

for batch in batches(sample, ITEMSINBATCH):
for item in batch:
print item
print "summary"

The client code is as clean as you can get...

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,265
Latest member
TodLarocca

Latest Threads

Top