Re: [Tutor] Why are these results different?

2009-11-19 Thread Alan Gauld


Stephen Nelson-Smith sanel...@gmail.com wrote



I'm seeing different behaviour between code that looks to be the same.
It obviously isn't the same, so I've misunderstood something:


In the first instance the two for-loops are inside the chain() call.
In the second you apply the chain inside the loops, so it only
applies to one item at a time.

logs = itertools.chain.from_iterable(glob.glob('%sded*/%s*%s.gz' % 
(source_dir, log, date)) for log in log_names for date in log_dates)

for log in logs:

...   print log
...
/Volumes/UNTITLED 1/ded1/access_log-20091105.gz
/Volumes/UNTITLED 1/ded2/access_log-20091105.gz



However:

for date in log_dates:
 for log in log_names:
logs = itertools.chain.from_iterable(glob.glob('%sded*/%s*%s.gz'
% (source_dir, log, date)))

Gives me one character at a time when I iterate over logs.


The final result is whatever chain() evaluated for the final loop 
iteration.

Apparently a string.

HTH,


--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/ 



___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Why are these results different?

2009-11-19 Thread Kent Johnson
On Thu, Nov 19, 2009 at 3:24 AM, Stephen Nelson-Smith
sanel...@gmail.com wrote:
 I'm seeing different behaviour between code that looks to be the same.
  It obviously isn't the same, so I've misunderstood something:


 log_names
 ('access', 'varnish')
 log_dates
 ('20091105', '20091106')
 logs = itertools.chain.from_iterable(glob.glob('%sded*/%s*%s.gz' % 
 (source_dir, log, date)) for log in log_names for date in log_dates)
 for log in logs:
 ...   print log

Here the argument to from_iterable() is a sequence of lists.
from_iterable() iterates each list in the sequence.

 However:

 for date in log_dates:
  for log in log_names:
     logs = itertools.chain.from_iterable(glob.glob('%sded*/%s*%s.gz'
 % (source_dir, log, date)))

 Gives me one character at a time when I iterate over logs.

Here the argument to from_iterable() is a list of strings, i.e. a
sequence of strings. from_iterable() iterates each string in the
sequence. Iterating a string yields each character in the string in
turn.

By the way do you know that the second version loops in a different
order than the first?

 Why is this?

 And how, then, can I make the first more readable?

Break out the argument to from_iterable() into a separate variable.
If you like spelling it out as separate loops, but you want a single
sequence, use the second form but put it in a generator function:
def log_file_names(log_names, log_dates):
  for date in log_dates:
   for log in log_names:
  for file_name in glob.glob('%sded*/%s*%s.gz' % (source_dir, log, date)):
yield file_name

Then your client code can say
for file_name in log_file_names(log_names, log_dates):
print file_name

If log_names is a constant you can put it into log_file_names()
instead of passing it as a parameter.

Kent
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor