What's up with this code?
Scott David Daniels
scott.daniels at acm.org
Wed Feb 22 20:05:47 EST 2006
Gregory Petrosyan wrote:
> Hello, it's me again.
> I am trying to optimise small module for working with polynomials, and
> I have encountered problem: new, optimised, code, doesn't work in some
> specific case. Here's the old version of the code:
>
> (3x^2 + 2x + 1 <=> poly([3, 2, 1]), btw)
>
> def __add__(self, other):
> "Return sum of two polynomials"
> rcoefs1 = list(reversed(self.coefs))
> rcoefs2 = list(reversed(other.coefs))
> coefs = [c1+c2 for c1,c2 in zip(rcoefs1, rcoefs2)]
> minlen = min(len(rcoefs1), len(rcoefs2))
> coefs.extend(rcoefs1[minlen:] + rcoefs2[minlen:])
> return Polynomial(reversed(coefs))
>
> Here's the new version:
>
> def __add__(self, other):
> rcoefs1 = reversed(self.coefs)
> rcoefs2 = reversed(other.coefs)
> coefs = [c1+c2 for c1,c2 in it.izip(rcoefs1, rcoefs2)]
> coefs.extend(it.chain(rcoefs1, rcoefs2)) #? -- here is magic
> if coefs[-1] != 0:
> return Polynomial(reversed(coefs), False, False)
> else:
> return Polynomial(reversed(coefs), False)
>
> Last four lines are ok (tested), "magic" seems to occure in #? line.
> What's the magic? Here it is:
>
> poly([1,2,1]) + poly([1,-2,1]) is ok,
> poly([1,-2,1]) + poly([5,4,3,2,1]) is ok,
> poly([1]) + poly([2]) is ok,
> poly([1,2,1]) + poly([5,4,3,2,1]) is ok, but
>
> poly([1,0]) + poly([-1]) gives poly([-1]),
> poly([1,-3]) + poly([-2]) gives poly([-5]) etc.
>
> "magic" happens when processing something like poly([a,b]) +
> poly([c]) and it gives poly([b+c]) as result. Can anybody help me with
> it?
OK, the trick is to think about how zip/izip _must_ work.
When the first list runs out first it stops. When the
second list runs out, it has already read ahead one element
of the first list.
def __add__(self, other):
shorter = reversed(self.coefs)
longer = reversed(other.coefs)
if len(self.coefs) > len(other.coefs):
shorter, longer = longer, shorter # insure shorter first
coefs = [c1+c2 for c1,c2 in it.izip(shorter, longer)]
if len(self.coefs) == len(other.coefs):
while coefs and coefs[-1] == 0:
coefs.pop()
else:
coefs.extend(longer)
...
--Scott David Daniels
scott.daniels at acm.org
More information about the Python-list
mailing list