FAQ
I've been teaching myself list comprehension, and i've run across something
i'm not able to convert.


here's the original code for matrix multiplcation


retmatrix = Matrix(self.__row,other.__col)
for m in range(0,retmatrix.__row):
for n in range(0,retmatrix.__col):
product = 0
for p in range(1,self.__col+1):
product += (self.__matrix[m][p] * other.__matrix[p][n])
retmatrix.__matrix[m][n] = product


Here is what i have so far:
retmatrix.__matrix = [[ product = product + (self.__matrix[m][p]*
other.__matrix[p][n])
if product else self.__matrix[m][p]* other.__matrix[p][n])
for p in range(0,self.col)
for n in range(0,self.col)]
for m in range(0,self.__row)]


But i know that isn't correct, can someone nudge my in the right direction?




--
Thanks
Kevin Anthony
www.NoSideRacing.com


Do you use Banshee?
Download the Community Extensions:
http://banshee.fm/download/extensions/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20121016/6205677b/attachment.html>

Search Discussions

  • Dave Angel at Oct 17, 2012 at 2:13 am

    On 10/16/2012 09:54 PM, Kevin Anthony wrote:
    I've been teaching myself list comprehension, and i've run across something
    i'm not able to convert.

    here's the original code for matrix multiplcation

    retmatrix = Matrix(self.__row,other.__col)
    for m in range(0,retmatrix.__row):
    for n in range(0,retmatrix.__col):
    product = 0
    for p in range(1,self.__col+1):
    product += (self.__matrix[m][p] * other.__matrix[p][n])
    retmatrix.__matrix[m][n] = product

    Here is what i have so far:
    retmatrix.__matrix = [[ product = product + (self.__matrix[m][p]*
    other.__matrix[p][n])
    if product else self.__matrix[m][p]* other.__matrix[p][n])
    for p in range(0,self.col)
    for n in range(0,self.col)]
    for m in range(0,self.__row)]

    But i know that isn't correct, can someone nudge my in the right direction?

    The biggest thing to learn about list comprehensions is when not to use
    them. I can't imagine how your latter version (even if correct) is
    clearer than the first.






    --


    DaveA
  • Dwight Hutto at Oct 17, 2012 at 2:22 am

    On Tue, Oct 16, 2012 at 10:13 PM, Dave Angel wrote:
    On 10/16/2012 09:54 PM, Kevin Anthony wrote:
    I've been teaching myself list comprehension, and i've run across something
    i'm not able to convert.

    here's the original code for matrix multiplcation

    retmatrix = Matrix(self.__row,other.__col)
    for m in range(0,retmatrix.__row):
    for n in range(0,retmatrix.__col):
    product = 0
    for p in range(1,self.__col+1):
    product += (self.__matrix[m][p] * other.__matrix[p][n])
    retmatrix.__matrix[m][n] = product

    Here is what i have so far:
    retmatrix.__matrix = [[ product = product + (self.__matrix[m][p]*
    other.__matrix[p][n])
    if product else self.__matrix[m][p]* other.__matrix[p][n])
    for p in range(0,self.col)
    for n in range(0,self.col)]
    for m in range(0,self.__row)]

    But i know that isn't correct, can someone nudge my in the right direction?
    The biggest thing to learn about list comprehensions is when not to use
    them. I can't imagine how your latter version (even if correct) is
    clearer than the first.

    I think he might be using the wrong function for a matrix
    multiplication, not that it's not workable, but there are other
    libraries like numpy that could help out.


    I wouldn't use list comprehension for this, unless it might be several
    lists that interact.
  • Dwight Hutto at Oct 17, 2012 at 2:24 am
    Try this in google:


    python matrix multiplication


    --
    Best Regards,
    David Hutto
    CEO: http://www.hitwebdevelopment.com
  • Kevin Anthony at Oct 17, 2012 at 4:43 am
    Is it not true that list comprehension is much faster the the for loops?


    If it is not the correct way of doing this, i appoligize.
    Like i said, I'm learing list comprehension.


    Thanks
    Kevin
    On Oct 16, 2012 10:14 PM, "Dave Angel" wrote:

    On 10/16/2012 09:54 PM, Kevin Anthony wrote:
    I've been teaching myself list comprehension, and i've run across something
    i'm not able to convert.

    here's the original code for matrix multiplcation

    retmatrix = Matrix(self.__row,other.__col)
    for m in range(0,retmatrix.__row):
    for n in range(0,retmatrix.__col):
    product = 0
    for p in range(1,self.__col+1):
    product += (self.__matrix[m][p] * other.__matrix[p][n])
    retmatrix.__matrix[m][n] = product

    Here is what i have so far:
    retmatrix.__matrix = [[ product = product + (self.__matrix[m][p]*
    other.__matrix[p][n])
    if product else self.__matrix[m][p]*
    other.__matrix[p][n])
    for p in range(0,self.col)
    for n in range(0,self.col)]
    for m in range(0,self.__row)]

    But i know that isn't correct, can someone nudge my in the right
    direction?
    The biggest thing to learn about list comprehensions is when not to use
    them. I can't imagine how your latter version (even if correct) is
    clearer than the first.



    --

    DaveA
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: <http://mail.python.org/pipermail/python-list/attachments/20121017/574c3e0a/attachment.html>
  • Dwight Hutto at Oct 17, 2012 at 5:09 am

    On Wed, Oct 17, 2012 at 12:43 AM, Kevin Anthony wrote:
    Is it not true that list comprehension is much faster the the for loops?

    If it is not the correct way of doing this, i appoligize.
    Like i said, I'm learing list comprehension.
    I thought it was matrix multiplication mixed with list comprehension.


    Check this out real quick from the docs for list comprehension, but if
    it's a mixture of matrix multi, and list comp, then reply back.


    http://docs.python.org/tutorial/datastructures.html#list-comprehensions




    --
    Best Regards,
    David Hutto
    CEO: http://www.hitwebdevelopment.com
  • Dwight Hutto at Oct 17, 2012 at 5:17 am
    And here is two more to read up on:


    http://www.scipy.org/FAQ#head-045cba7978d75ec548822222150fa6ad308e325a


    www.python-course.eu/matrix_arithmetic.php
    --
    Best Regards,
    David Hutto
    CEO: http://www.hitwebdevelopment.com
  • Oscar Benjamin at Oct 17, 2012 at 10:34 pm

    On 17 October 2012 06:09, Dwight Hutto wrote:
    On Wed, Oct 17, 2012 at 12:43 AM, Kevin Anthony
    wrote:
    Is it not true that list comprehension is much faster the the for loops?

    If it is not the correct way of doing this, i appoligize.
    Like i said, I'm learing list comprehension.
    I thought it was matrix multiplication mixed with list comprehension.

    Check this out real quick from the docs for list comprehension, but if
    it's a mixture of matrix multi, and list comp, then reply back.

    http://docs.python.org/tutorial/datastructures.html#list-comprehensions

    If you're looking for a fast solution then you should follow David's
    suggestion and use numpy:


    The most relevant numpy function is numpy.dot:
    http://docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html




    Oscar


    P.S. David, it was a bit fiddly for me to quote your response because
    the relevant part was in a post that had no context. Also your name is
    listed as Dwight above. That is automatically added by gmail because
    of the settings in your own email client. You may need to change your
    account settings if you want it to say David when people quote you.
  • Dave Angel at Oct 17, 2012 at 12:32 pm

    On 10/17/2012 12:43 AM, Kevin Anthony wrote:
    Is it not true that list comprehension is much faster the the for loops?

    If it is not the correct way of doing this, i appoligize.
    Like i said, I'm learing list comprehension.
    (Please don't top-post; it ruins the ordering. In these forums, put
    your response after the part you quote from earlier messages. Or even
    better, after each part you quote. Then trim off the parts you didn't
    reference.)


    list comprehensions CAN be much faster, but not necessarily. The most
    complex a loop, the less likely it'll help much.


    In any case, only the inner loop will be affected. Nesting two list
    comprehensions will make a trivial difference.


    On the other hand, Hans Mulder shows some other factoring which seems
    much more readable than yours.


    Studying (and testing) those could teach you a lot about comprehensions,
    as well as about the libraries that can help. Note especially what
    zip(*b) yields, and think about what it means.




    --


    DaveA
  • Rusi at Oct 17, 2012 at 2:06 pm

    On Oct 17, 5:33?pm, Dave Angel wrote:
    On 10/17/2012 12:43 AM, Kevin Anthony wrote:> Is it not true that list comprehension is much faster the the for loops?
    If it is not the correct way of doing this, i appoligize.
    Like i said, I'm learing list comprehension.
    list comprehensions CAN be much faster, but not necessarily. ?The most
    complex a loop, the less likely it'll help much.

    One-lining the comprehension seems to make a difference of about 10%
    out here. Maybe Ive missed something? Seems too large?


    # My original suggestion
    def dot(p,q): return sum (x*y for x,y in zip(p,q))
    def transpose(m): return zip(*m)
    def mm(a,b): return mmt(a, transpose(b))
    def mmt(a,b): return [[dot(ra, rb) for rb in b] for ra in a]


    # One-liner (Thanks Hans for reminding me of sum)


    def mm1(a,b): return [[sum([x*y for x,y in zip(ra,rb)]) for rb in
    zip(*b)] for ra in a]

    t1=Timer("res=mm1(m,m)", setup="from __main__ import mm1, m")
    t1.timeit(1000)
    12.276363849639893
    t0=Timer("res=mm(m,m)", setup="from __main__ import mm, m")
    t0.timeit(1000)
    13.453603029251099
  • Rusi at Oct 17, 2012 at 2:33 pm

    On Oct 17, 7:06?pm, rusi wrote:
    On Oct 17, 5:33?pm, Dave Angel wrote:

    On 10/17/2012 12:43 AM, Kevin Anthony wrote:> Is it not true that list comprehension is much faster the the for loops?
    If it is not the correct way of doing this, i appoligize.
    Like i said, I'm learing list comprehension.
    list comprehensions CAN be much faster, but not necessarily. ?The most
    complex a loop, the less likely it'll help much.
    One-lining the comprehension seems to make a difference of about 10%
    out here. Maybe Ive missed something? Seems too large?

    # My original suggestion
    def dot(p,q): return sum (x*y for x,y in zip(p,q))
    def transpose(m): return zip(*m)
    def mm(a,b): return mmt(a, transpose(b))
    def mmt(a,b): return [[dot(ra, rb) for rb in b] for ra in a]

    # One-liner (Thanks Hans for reminding me of sum)

    def mm1(a,b): return [[sum([x*y for x,y in zip(ra,rb)]) for rb in
    zip(*b)] for ra in a]
    t1=Timer("res=mm1(m,m)", setup="from __main__ import mm1, m")
    t1.timeit(1000)
    12.276363849639893
    t0=Timer("res=mm(m,m)", setup="from __main__ import mm, m")
    t0.timeit(1000)
    13.453603029251099

    In case anyone wants to try out with the same data, I used:


    m = [range(i,i+30) for i in range(30)]
  • Dave Angel at Oct 17, 2012 at 2:36 pm

    On 10/17/2012 10:06 AM, rusi wrote:
    On Oct 17, 5:33 pm, Dave Angel wrote:
    On 10/17/2012 12:43 AM, Kevin Anthony wrote:> Is it not true that list comprehension is much faster the the for loops?
    If it is not the correct way of doing this, i appoligize.
    Like i said, I'm learing list comprehension.
    list comprehensions CAN be much faster, but not necessarily. The most
    complex a loop, the less likely it'll help much.
    One-lining the comprehension seems to make a difference of about 10%
    out here. Maybe Ive missed something? Seems too large?

    # My original suggestion
    def dot(p,q): return sum (x*y for x,y in zip(p,q))
    def transpose(m): return zip(*m)
    def mm(a,b): return mmt(a, transpose(b))
    def mmt(a,b): return [[dot(ra, rb) for rb in b] for ra in a]

    # One-liner (Thanks Hans for reminding me of sum)

    def mm1(a,b): return [[sum([x*y for x,y in zip(ra,rb)]) for rb in
    zip(*b)] for ra in a]
    t1=Timer("res=mm1(m,m)", setup="from __main__ import mm1, m")
    t1.timeit(1000)
    12.276363849639893
    t0=Timer("res=mm(m,m)", setup="from __main__ import mm, m")
    t0.timeit(1000)
    13.453603029251099

    And I'd wager all the improvement is in the inner loop, the dot() function.




    --


    DaveA
  • 88888 Dihedral at Oct 17, 2012 at 2:45 pm
    Dave Angel? 2012?10?17????UTC+8??10?37?01????
    On 10/17/2012 10:06 AM, rusi wrote:
    On Oct 17, 5:33 pm, Dave Angel wrote:

    On 10/17/2012 12:43 AM, Kevin Anthony wrote:> Is it not true that list comprehension is much faster the the for loops?

    If it is not the correct way of doing this, i appoligize.
    Like i said, I'm learing list comprehension.
    list comprehensions CAN be much faster, but not necessarily. The most
    complex a loop, the less likely it'll help much.
    One-lining the comprehension seems to make a difference of about 10%
    out here. Maybe Ive missed something? Seems too large???

    # My original suggestion
    def dot(p,q): return sum (x*y for x,y in zip(p,q))
    def transpose(m): return zip(*m)
    def mm(a,b): return mmt(a, transpose(b))
    def mmt(a,b): return [[dot(ra, rb) for rb in b] for ra in a]

    # One-liner (Thanks Hans for reminding me of sum)

    def mm1(a,b): return [[sum([x*y for x,y in zip(ra,rb)]) for rb in
    zip(*b)] for ra in a]

    t1=Timer("res=mm1(m,m)", setup="from __main__ import mm1, m")
    t1.timeit(1000)
    12.276363849639893
    t0=Timer("res=mm(m,m)", setup="from __main__ import mm, m")
    t0.timeit(1000)
    13.453603029251099


    And I'd wager all the improvement is in the inner loop, the dot() function.





    --



    DaveA

    Thanks for the tips of matrix operations over some fields or rings
    other than the real field and the complex field.
  • Rusi at Oct 17, 2012 at 2:50 pm

    On Oct 17, 7:37?pm, Dave Angel wrote:


    And I'd wager all the improvement is in the inner loop, the dot() function.

    Sorry -- red herring!


    Changing


    def mm1(a,b): return [[sum(x*y for x,y in zip(ra,rb)) for rb in
    zip(*b)] for ra in a]


    to


    def mm1(a,b): return [[sum([x*y for x,y in zip(ra,rb)]) for rb in
    zip(*b)] for ra in a]


    makes the speed diff vanish
  • 88888 Dihedral at Oct 17, 2012 at 3:06 pm
    rusi? 2012?10?17????UTC+8??10?50?11????
    On Oct 17, 7:37?pm, Dave Angel wrote:


    And I'd wager all the improvement is in the inner loop, the dot() function.


    Sorry -- red herring!



    Changing



    def mm1(a,b): return [[sum(x*y for x,y in zip(ra,rb)) for rb in

    zip(*b)] for ra in a]



    to



    def mm1(a,b): return [[sum([x*y for x,y in zip(ra,rb)]) for rb in

    zip(*b)] for ra in a]



    makes the speed diff vanish

    I think a lot people don't work on computations over
    fields other real and complex.


    That is why a lot people keep complaining about the speeds
    of python programs executed.
  • Dwight Hutto at Oct 17, 2012 at 2:19 am

    On Tue, Oct 16, 2012 at 10:13 PM, Dwight Hutto wrote:
    On Tue, Oct 16, 2012 at 9:54 PM, Kevin Anthony
    wrote:
    I've been teaching myself list comprehension, and i've run across something
    i'm not able to convert.

    here's the original code for matrix multiplcation

    retmatrix = Matrix(self.__row,other.__col)
    for m in range(0,retmatrix.__row):
    for n in range(0,retmatrix.__col):
    product = 0
    for p in range(1,self.__col+1):
    product += (self.__matrix[m][p] * other.__matrix[p][n])
    retmatrix.__matrix[m][n] = product

    Here is what i have so far:
    retmatrix.__matrix = [[ product = product + (self.__matrix[m][p]*
    other.__matrix[p][n])
    if product else self.__matrix[m][p]* other.__matrix[p][n])
    for p in range(0,self.col)
    for n in range(0,self.col)]
    for m in range(0,self.__row)]

    But i know that isn't correct, can someone nudge my in the right direction?


    --
    Thanks
    Kevin Anthony
    www.NoSideRacing.com

    Do you use Banshee?
    Download the Community Extensions:
    http://banshee.fm/download/extensions/


    --
    http://mail.python.org/mailman/listinfo/python-list

    I did this a little while back for something else, but memories get
    jumbled up in these molecules of data I have floating around in my
    mind, but maybe this will put you on the right track.


    --

    I know this doesn't answer the python question, but it will help you
    algorithm out what you need to know.


    I do lots of interdisciplinary research, so if this doesn't help, let
    me know, and I'll take a refresher, and work up some code. Also, look
    at numpy.
    --
    Best Regards,
    David Hutto
    CEO: http://www.hitwebdevelopment.com
  • Rusi at Oct 17, 2012 at 3:30 am

    On Oct 17, 7:14?am, Dave Angel wrote:
    On 10/16/2012 09:54 PM, Kevin Anthony wrote:








    I've been teaching myself list comprehension, and i've run across something
    i'm not able to convert.
    here's the original code for matrix multiplcation
    retmatrix = Matrix(self.__row,other.__col)
    for m in range(0,retmatrix.__row):
    ? ? for n in range(0,retmatrix.__col):
    ? ? ? ? product = 0
    ? ? ? ? for p in range(1,self.__col+1):
    ? ? ? ? ? ? product += (self.__matrix[m][p] * other.__matrix[p][n])
    ? ? ? ? retmatrix.__matrix[m][n] = product
    Here is what i have so far:
    retmatrix.__matrix = [[ product = product + (self.__matrix[m][p]*
    other.__matrix[p][n])
    ? ? ? ? ? ? ? ? ?if product else self.__matrix[m][p]* other.__matrix[p][n])
    ? ? ? ? ? ? ? ? ?for p in range(0,self.col)
    ? ? ? ? ? ? ? ? ?for n in range(0,self.col)]
    ? ? ? ? ? ? ? ? ?for m in range(0,self.__row)]
    But i know that isn't correct, can someone nudge my in the right direction?
    The biggest thing to learn about list comprehensions is when not to use
    them. ?I can't imagine how your latter version (even if correct) is
    clearer than the first.

    --

    DaveA

    Try rewriting using dot


    from operator import mul
    def dot(p,q):
    return reduce(mul, [x*y for x,y in zip(p,q)]) # the [] can become
    ()


    and avoiding object-orientation (at least to start with)
  • Terry Reedy at Oct 17, 2012 at 5:21 am

    On 10/16/2012 9:54 PM, Kevin Anthony wrote:
    I've been teaching myself list comprehension, and i've run across
    something i'm not able to convert.

    list comprehensions specifically abbreviate the code that they are
    (essentially) equivalent to.


    res = []
    for item in source:
    res.append(f(item))
    res


    <==>


    [f(item) for item in source]


    Matrix multiplication does not fit the pattern above. The reduction is
    number addition rather than list appending.


    --
    Terry Jan Reedy
  • Rusi at Oct 17, 2012 at 7:13 am

    On Oct 17, 10:22?am, Terry Reedy wrote:
    On 10/16/2012 9:54 PM, Kevin Anthony wrote:

    I've been teaching myself list comprehension, and i've run across
    something i'm not able to convert.
    list comprehensions specifically abbreviate the code that they are
    (essentially) equivalent to.

    res = []
    for item in source:
    ? ?res.append(f(item))
    res

    <==>

    [f(item) for item in source]

    Matrix multiplication does not fit the pattern above. The reduction is
    number addition rather than list appending.

    Dunno why you say that. Heres matrix multiply using list
    comprehensions:


    from operator import add
    def dot(p,q): return reduce(add, (x*y for x,y in zip(p,q)))


    def transpose(m): return zip(*m)


    def mm(a,b): return mmt(a, transpose(b))


    def mmt(a,b): return [[dot(ra, rb) for rb in b] for ra in a]


    which can then be 'reduced' to a one-liner if that takes your fancy
  • Hans Mulder at Oct 17, 2012 at 8:34 am

    On 17/10/12 09:13:57, rusi wrote:
    On Oct 17, 10:22 am, Terry Reedy wrote:
    On 10/16/2012 9:54 PM, Kevin Anthony wrote:

    I've been teaching myself list comprehension, and i've run across
    something i'm not able to convert.
    list comprehensions specifically abbreviate the code that they are
    (essentially) equivalent to.

    res = []
    for item in source:
    res.append(f(item))
    res

    <==>

    [f(item) for item in source]

    Matrix multiplication does not fit the pattern above. The reduction is
    number addition rather than list appending.
    Dunno why you say that. Heres matrix multiply using list
    comprehensions:

    from operator import add
    def dot(p,q): return reduce(add, (x*y for x,y in zip(p,q)))

    def transpose(m): return zip(*m)

    def mm(a,b): return mmt(a, transpose(b))

    def mmt(a,b): return [[dot(ra, rb) for rb in b] for ra in a]

    which can then be 'reduced' to a one-liner if that takes your fancy

    I can golf it down to two lines without losing readability:


    def dot(p,q): return sum(x*y for x,y in zip(p,q))


    def mm(a,b): return [[dot(ra, rb) for rb in zip(*b)] for ra in a]




    Hope this helps,


    -- HansM
  • Terry Reedy at Oct 17, 2012 at 9:46 pm

    On 10/17/2012 3:13 AM, rusi wrote:
    On Oct 17, 10:22 am, Terry Reedy wrote:
    On 10/16/2012 9:54 PM, Kevin Anthony wrote:

    I've been teaching myself list comprehension, and i've run across
    something i'm not able to convert.

    My response is to the part Kevin could *not* convert, not the parts he
    did convert. I attempted to explain why he could not convert that part.

    list comprehensions specifically abbreviate the code that they are
    (essentially) equivalent to.

    res = []
    for item in source:
    res.append(f(item))
    res

    <==>

    [f(item) for item in source]

    Matrix multiplication does not fit the pattern above. The reduction is
    number addition rather than list appending.
    Dunno why you say that.

    Because it is true and because it makes an essential point about what
    one can and cannot sensibly do with comprehensions. They are not
    intended to be a replacement for *all* loops.


    The essential inner reduction by addition of products that Kevin was
    'not able to convert' cannot be converted (with out some obnoxious
    trickery and *some* extra helper), so his request for a sensible
    conversion is futile.

    Heres matrix multiply using list comprehensions:

    plus a helper function that does the inner reduction otherwise, as I
    implied it should be

    from operator import add
    def dot(p,q): return reduce(add, (x*y for x,y in zip(p,q)))

    Right, this is the addition reduction that the OP was trying to
    convert to a list comp. It cannot be done and you have not done it
    either. Note the the vector of products is produced as a comprehension.
    That you left it as a 'generator expression' is not relevant.


    The important point is the the addition combines the products of
    different iterations and list comps, by their nature, cannot directly do
    that.

    def transpose(m): return zip(*m)

    def mm(a,b): return mmt(a, transpose(b))

    def mmt(a,b): return [[dot(ra, rb) for rb in b] for ra in a]

    This is the repeated append part of the original nested loops and that,
    as I said, can be re-expressed as a list comp. But that was not the part
    Kevin was having difficulty with and not the part I was talking about.


    --
    Terry Jan Reedy

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedOct 17, '12 at 1:54a
activeOct 17, '12 at 10:34p
posts21
users8
websitepython.org

People

Translate

site design / logo © 2023 Grokbase