python - What's an elegant way for one loop iteration to affect another? -


i needed process config file now. because of way generated, contains lines this:

---(more 15%)--- 

the first step strip these unwanted lines out. slight twist, each of these lines followed blank line, want strip. created quick python script this:

skip_next = false line in sys.stdin:     if skip_next:         skip_next = false         continue         if line.startswith('---(more'):         skip_next = true         continue         print line, 

now, works, it's more hacky i'd hoped. difficulty when looping through lines, want content of 1 line affect subsequent line. hence question: what's elegant way 1 loop iteration affect another?

another way itertools.tee, allows split iterator two. can advance 1 iterator 1 step, putting 1 iterator 1 line ahead of other. can zip 2 iterators , @ both previous line , current line @ each step of for loop (i use izip_longest doesn't drop last line):

from itertools import tee, izip_longest in1, in2 = tee(sys.stdin, 2) next(in2) line, prevline in izip_longest(in1, in2, fillvalue=''):     if line.startswith('---(more') or prevline.startswith('---(more'):         continue     print line 

this done equivalent generator expression:

from itertools import tee, izip_longest in1, in2 = tee(sys.stdin, 2) next(in2) pairs = izip_longest(in1, in2, fillvalue='') res = (line line, prevline in pairs        if not line.startswith('---(more') , not prevline.startswith('---(more')) line in res:     print line 

or use filter, allows drop iterator items when condition not true.

from itertools import tee, izip_longest in1, in2 = tee(sys.stdin, 2) next(in2) pairs = izip_longest(in1, in2, fillvalue='') cond = lambda pair: not pair[0].startswith('---(more') , not pair[1].startswith('---(more') res = filter(cond, pairs) line in res:     print line 

if willing go outside python standard library, toolz package makes easier. provides sliding_window function, allows split iterator such a b c d e f (a,b), (b,c), (c,d), (d,e), (e,f). same thing tee approach above, combined 3 lines one:

from toolz.itertoolz import sliding_window line, prevline in sliding_wind(2, sys.stdin):     if line.startswith('---(more') or prevline.startswith('---(more'):         continue     print line 

you additionally use remove, opposite of filter, drop items without needing for loop:

from tools.itertoolz import sliding_window, remove pairs = sliding_window(2, sys.stdin) cond = lambda x: x[0].startswith('---(more') or x[1].startswith('---(more') res = remove(cond, pairs) line in res:     print line 

Comments

Popular posts from this blog

How to run C# code using mono without Xamarin in Android? -

python - Specify path of savefig with pylab or matplotlib -

c# - SharpSsh Command Execution -