嗨,我正在使用 python 中的矩阵,称之为a
:
a = [
[0,0,0],
[0,0,0],
[0,0,0]
]
我想将第一列第二行的元素 (a[1][0]
) 更改为 1,产生以下结果:
a = [
[0,0,0],
[1,0,0],
[0,0,0]
]
您当然可以通过以下方式轻松完成此任务:
a[1][0] = 1
不幸的是,我是个疯子,想完成这个纯粹的功能:) 条件是:
- 变量状态不会改变,您应该能够用常量替换所有变量。
- 不使用状态完整运算符,例如
for in
。 - 变量
a
元素发生更改后的结果将存储在第二个变量b
中,而不会更改a
。 - 该解决方案不应使用任何导入或依赖项。
想要的结果应该是这样的:
a = [
[0,0,0],
[0,0,0],
[0,0,0]
]
b = someOperation(a)
assert a == [[0,0,0],[0,0,0],[0,0,0]]
assert b == [[0,0,0],[1,0,0],[0,0,0]]
# the above asserts should not trigger
有人知道我的问题的(纯功能性)解决方案吗? 提前致谢。
最佳答案
如果您想要纯粹的函数式方式来执行此类操作,您可能需要考虑如何在 Haskell 中执行此操作。 - 函数式编程的黄金标准。
对于小型的临时问题,如果您需要通过索引访问元素,通常会使用数字生成器压缩您的数据序列:
ghci> zip [0..] "abc"
[(0,'a'),(1,'b'),(2,'c')]
您可以在 Python 中执行相同的操作:
from itertools import count
def index_list(lst):
return zip(count(), lst)
在'abc'
上使用它:
>>> list(index_list('abc'))
[(0, 'a'), (1, 'b'), (2, 'c')]
(在上面的示例中我仅使用 list
来显示结果。)
同样,您可以索引包含矩阵的嵌套列表:
def index_matrix(matrix):
return index_list(map(index_list, matrix))
您现在有了一个元组映射的映射,其中元组的第一个元素是行或列索引,第二个元素是索引的值。
我们可以使用 OP 的输入在 Haskell 中执行相同的操作:
ghci> fmap (fmap (zip [0..])) $ zip [0..] [[0,0,0],[0,0,0],[0,0,0]]
[(0,[(0,0),(1,0),(2,0)]),(1,[(0,0),(1,0),(2,0)]),(2,[(0,0),(1,0),(2,0)])]
index_matrix
Python 函数在概念上产生相同形状的输出,但由 zip 和 map 对象组成。
由于 index_matrix
已对行和列进行索引,因此您现在可以迭代 map 的 map 并替换特定行和列处的值:
def replace_in_matrix(matrix, row, col, value):
return map(lambda r:
map(lambda c:
value if r[0] == row and c[0] == col else c[1], r[1]), index_matrix(matrix))
在 OP 矩阵上尝试一下:
>>> m = [[0,0,0],[0,0,0],[0,0,0]]
>>> result = replace_in_matrix(m, 1, 0, 1)
>>> list(map(list, result))
[[0, 0, 0], [1, 0, 0], [0, 0, 0]]
>>> m
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
这也表明 m
保持不变。
Haskell 中的临时投影类似:
ghci> fmap (fmap snd)
$ fmap snd
$ fmap (\(i, rs) -> (i, fmap (\(j, x) -> (j, if i == 1 && j == 0 then 1 else x)) rs))
$ fmap (fmap (zip [0..]))
$ zip [0..] [[0,0,0],[0,0,0],[0,0,0]]
[[0,0,0],[1,0,0],[0,0,0]]
(我插入了一些换行符以稍微提高可读性。)
关于python - 仅使用常量python更改矩阵中的嵌套元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74693103/