Last active
November 20, 2015 14:24
-
-
Save sr105/694deeca9acb55618434 to your computer and use it in GitHub Desktop.
Answer for [Can I yield from an instance method](http://stackoverflow.com/q/33818422/47078)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from itertools import izip_longest, izip, tee | |
import random | |
# Similar to itertools.islice | |
class Nth(object): | |
def __init__(self, n): | |
self.n = n | |
self.i = 0 | |
self.nout = 0 | |
def itervalues(self, x): | |
self.i = 0 | |
self.nout = 0 | |
for xi in x: | |
self.i += 1 | |
if self.i == self.n: | |
self.i = 0 | |
self.nout += 1 | |
yield self.nout, xi | |
def add(x,y): | |
for xi,yi in izip(x,y): | |
yield xi + yi | |
def sub(x,y): | |
for xi,yi in izip(x,y): | |
yield xi - yi | |
class NthSumDiff(object): | |
def __init__(self, n): | |
self.nthsum = Nth(n) | |
self.nthdiff = Nth(n) | |
def itervalues(self, x, y): | |
xadd, xsub = tee(x) | |
yadd, ysub = tee(y) | |
gen_sum = self.nthsum.itervalues(add(xadd, yadd)) | |
gen_diff = self.nthdiff.itervalues(sub(xsub, ysub)) | |
# Have to use izip_longest here, but why? | |
#for (i,nthsum), (j,nthdiff) in izip_longest(gen_sum, gen_diff): | |
for (i,nthsum), (j,nthdiff) in izip(gen_sum, gen_diff): | |
assert i==j, "sum row %d != diff row %d" % (i,j) | |
yield nthsum, nthdiff | |
nskip = 12 | |
ns = Nth(nskip) | |
nd = Nth(nskip) | |
nsd = NthSumDiff(nskip) | |
nfiles = 10 | |
for i in range(nfiles): | |
# Generate some data. | |
# If the block length is a multiple of nskip there's no problem. | |
#n = random.randint(5000, 10000) * nskip | |
n = random.randint(50000, 100000) | |
print 'file %d n=%d' % (i, n) | |
x = range(n) | |
y = range(100,n+100) | |
# Independent processing is no problem but requires two loops. | |
for i, nthsum in ns.itervalues(add(x,y)): | |
pass | |
for j, nthdiff in nd.itervalues(sub(x,y)): | |
pass | |
assert i==j | |
# Trying to do both with one loops causes problems. | |
for nthsum, nthdiff in nsd.itervalues(x,y): | |
# If izip_longest is necessary, why don't I ever get a fillvalue? | |
assert nthsum is not None | |
assert nthdiff is not None | |
# After each block of data the two iterators should have the same state. | |
assert nsd.nthsum.nout == nsd.nthdiff.nout, \ | |
"sum nout %d != diff nout %d" % (nsd.nthsum.nout, nsd.nthdiff.nout) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment