Programming Forums

Programming Forums (http://www.programmingforums.org/forumindex.php)
-   Python (http://www.programmingforums.org/forum43.html)
-   -   How would you write this in Python? (http://www.programmingforums.org/showthread.php?t=10679)

DaWei Jul 10th, 2006 3:04 PM

How would you write this in Python?
 
:

for (a = i = 0; i < 3; ++i)
  for (j = 0; j < 3; ++j)
      a += grid [i][j] * map [i][j]


Further, would you consider converting the lists of lists into single lists?

Also, would you move invariants (such as 2*math.pi or myImage.GetWidth ()) outside the comprehension to avoid the overhead?

titaniumdecoy Jul 10th, 2006 3:31 PM

I believe this would be the equivalent in Python:

:

a = 0
for i in range(3):
    for j in range(3):
        a += grid[i][j] * map[i][j]


Arevos Jul 10th, 2006 4:16 PM

It might be more Pythonic to use a generator and sum:
:

a = sum(grid[i][j] * map[i][j] for j in range(3) for i in range(3))
But this seems a little hard to read.

However, I haven't yet devised a better solution. I'll think about it, and see if I can't come up with something more elegant.

Arevos Jul 10th, 2006 4:27 PM

Frankly, what Python really needs is a n-dimensional rectangular grid object. Something like:
:

grid = Array(3, 3)    # 3 by 3 array
map  = Array(3, 3)

a = sum(x * y for x in grid.items() for y in map.items())

I don't believe the standard Python library has this functionality.

DaWei Jul 10th, 2006 5:02 PM

I thought about using a generator to flatten them to one dimension, then operate on those. I appreciate your looking at it. I still am, too. You got the thrust of my question; I knew how to just translate it.

titaniumdecoy Jul 10th, 2006 5:34 PM

I believe the numpy module supports multidimensional arrays.

Arevos Jul 10th, 2006 6:39 PM

Quote:

Originally Posted by titaniumdecoy
I believe the numpy module supports multidimensional arrays.

Mm, that thought had crossed my mind, too. However, Numeric arrays are limited to numerical data, and there's no "flatten" capability, so it's not particularly any better than using lists.

Speaking of flattening lists:
:

def flatten(seq):
    if type(seq) is not list:
        return [seq]
    return reduce(lambda x, y : x + flatten(y), seq, [])

Ah, reduce, so much power in such a little function.

Armed with the above function, this should work.
:

a = sum(x * y for x in flatten(grid) for y in flatten(map))
This approach can be optimised further by constructing a generator flatten function. However, if you're only dealing with 3 by 3 lists, then there's not much point.

titaniumdecoy Jul 10th, 2006 6:52 PM

Arevos, I'm not 100% sure about this but I believe your logic is flawed. You are multiplying each value in the first list by each value in second list and adding the results, while the original code multiplies each value in the first list only by the single corresponding value in the second list and adds the results.

I wrote a function, align, that allows you to achieve this functionality:

:

def align(a, b, func):
    """Yield result of func on items from lists a and b with matching indices"""
    assert len(a) == len(b)
    for i in range(len(a)):
        if not isinstance(a[i], list) and not isinstance(b[i], list):
            yield func(a[i], b[i])
        else:
            for result in align(a[i], b[i], func):
                yield result

This can then be used to achieve the original task as follows:

:

a = sum(align(grid, map, lambda x, y: x * y))

Arevos Jul 10th, 2006 7:12 PM

Quote:

Originally Posted by titaniumdecoy
Arevos, I'm not 100% sure about this but I believe your logic is flawed.

Yes, you're quite correct. I had the right answer originally, then edited my post and inserted the wrong one. D'oh!

The original code I had went:
:

a = sum(x * y for x, y in zip(flatten(grid), flatten(map)))
Which I think should work. I got rather confused, however, and forgot how my code worked :o

titaniumdecoy Jul 10th, 2006 7:20 PM

Oh, wow! I didn't know you could iterate over multiple variables in a list comprehension! Well, that makes my code almost useless. :p

I originally wrote a flatten function as well, but since I couldn't figure out how to do just that, I wrote a new function, align.

By the way, what does the zip function do?


All times are GMT -5. The time now is 12:18 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC