Python:使用列表推导式生成对称数组

4
我正在尝试生成一个矩阵 A == [f(i,j) for i,j in range(0,n)]。该矩阵是对称的 (f(i,j) == f(j,i)) 且对角元素为零 (f(i,i) == 0)
问题:是否可能生成此矩阵的列表理解式,但仅对 i < j 调用函数 f(i,j)
不是我的问题:以其他方式生成对称矩阵。
一种可能的解决方案是,通过辅助函数 g 调用 f 并将其值保存在额外的存储器中或返回已存储的值。
是否可能避免使用额外的存储器来解决这个问题?我不确定这个额外障碍是否意味着需要从自身引用列表理解式(Python 中没有此功能),但希望我缺少其他技巧。

这可能会给你一个很好的起点:https://dev59.com/cWw05IYBdhLWcg3w3ViX - BrandonM
@BrandonM 是的,使用列表推导式制作一个包含对角线为零的上三角矩阵也很容易。 - myfirsttime1
2个回答

2

假设您确实需要完整的矩阵,尽管它是对称的,您可以这样做。

首先创建矩阵A。(我知道这意味着您不能在列表理解中生成它。)在这里,我定义了一个“虚拟”的函数f,并假设n的值为3。

>>> 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

如果我理解你的意思正确,那么不需要额外的存储空间。在一个列表推导式中调用 subsg 函数即可。


这被视为一种解决方案。 - myfirsttime1

1
如果您希望该函数仅在i < j时执行,则可以使用lru_cache (@lru_cache)将函数的结果保存在缓存中,并在i > j时直接使用它而无需重新计算。
from typing import Any
from functools import lru_cache

@lru_cache()
def f(i: int, j: int) -> Any:
    return i * (-j)

n = 5
m = [f(i, j) if i < j else f(j, i) if i > j else 0 for i in range(n) for j in range(n)]

for i in range(0, n * n, n):
    print(m[i: i + n])

结果为

[0, 0, 0, 0, 0]
[0, 0, -2, -3, -4]
[0, -2, 0, -6, -8]
[0, -3, -6, 0, -12]
[0, -4, -8, -12, 0]

很酷。lru_cache。之前不知道这个。 - myfirsttime1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接