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

时间:2016-10-23 13:32:07

标签: python arrays list-comprehension

我正在尝试生成矩阵std::deque。矩阵是对称的A == [f(i,j) for i,j in range(0,n)],对角元素是零(f(i,j) == f(j,i))

问题:是否可以生成一个列表推导,生成此矩阵但只调用(f(i,i) == 0)的函数f(i,j)

不是我的问题:以其他方式生成对称矩阵。

可能的解决方案:通过辅助函数i < j调用f,将g的值保存在其他存储中或返回存储的值

是否可以解决避免额外存储的问题? 我不确定这个额外的障碍是否意味着对自己的列表理解的引用(我在Python中读不存在)是必要的,希望我错过了其他一些技巧。

2 个答案:

答案 0 :(得分: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

如果我理解正确,就不需要额外的存储空间。在练习潜艇的列表理解中调用 g

答案 1 :(得分:1)

如果您希望该功能仅在i&lt; j,你可以使用lru_cache(@lru_cache)将函数的结果保存在缓存中,并直接使用它而无需在i> 1时重新计算它。学家

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]