myfirsttime1 myfirsttime1 - 3 years ago 196
Python Question

Python: Generating a symmetric array with list comprehension

I am trying to generate a matrix

A == [f(i,j) for i,j in range(0,n)]
. The matrix is symmetric
(f(i,j) == f(j,i))
and the diagonal elements are zero
(f(i,i) == 0)

Question: Is it possible to produce a list comprehension that generates this matrix but that only calls the function
i < j

Not my question: Generate the symmetric matrix in some other way.

Possible solution: Make the call to
through an auxiliary function
that saves the value of
in an additional storage or returns the stored value.

Would it be possible to solve avoiding the additional storage?
I am not sure if this additional handicap implies that a reference to the list comprehension from itself (which I read doesn't exist in Python) is necessary, hopefully I am missing some other trick.

Answer Source

Assuming you really need the full matrix, in spite of its being symmetric, you could do this.

Create the matrix A first. (I know, this means you're not generating it in a list comprehension.) Here I define a 'dummy' function f and assume a value of 3 for n.

>>> n=3
>>> subs=((i,j) for i in range(n) for j in range(3) if i<=j)
>>> for i,j in subs:
...     i,j
(0, 0)
(0, 1)
(0, 2)
(1, 1)
(1, 2)
(2, 2)
>>> def f(i,j):
...     return
>>> def g(i,j):
...     if i==j:
...         A[i,i] = 0
...     else:
...         val=f(i,j)
...         A[i,j]=val
...         A[j,i]=val

If I've understood you correctly, there's no need for extra storage. Call g in a list comprehension that exercises subs.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download