myfirsttime1 myfirsttime1 - 1 month ago 7
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
f(i,j)
for
i < j
?

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




Possible solution: Make the call to
f
through an auxiliary function
g
that saves the value of
f
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

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.