Python设置多行的矩阵值,每个行有多个不同的列,没有for循环

Python设置多行的矩阵值,每个行有多个不同的列,没有for循环,python,matrix,indexing,Python,Matrix,Indexing,如何在不使用for循环的情况下,为多行矩阵和具有不同列号的每行矩阵设置相同的值? 例如,矩阵a: a=matrix([[1,2,3], [8,2,9], [1,8,7]]) row = [1,2,3] col = [[1,2] [1,3] [2,3]] 我想把a[1,1],a[1,2],a[2,1],a[2,3],a[3,2],a[3,3]设置为相同的值。 我知道循环的用途: for i in xrange(len(ro

如何在不使用for循环的情况下,为多行矩阵和具有不同列号的每行矩阵设置相同的值? 例如,矩阵a:

a=matrix([[1,2,3],
          [8,2,9],
          [1,8,7]])

row = [1,2,3]
col = [[1,2]
       [1,3]
       [2,3]]  
我想把a[1,1],a[1,2],a[2,1],a[2,3],a[3,2],a[3,3]设置为相同的值。 我知道循环的用途:

for i in xrange(len(row)):
    a[row[i],col[i]] = setvalue    

但是在没有for循环的情况下,还有其他方法可以做到这一点吗?

案例1:使用列表理解

您可以这样做:

value = 2
col_length = 3
line_length = 3
a = [[value for x in range(col_length)] for x in range(line_length)]
def set_items_to(mx, indices, value=0):
  sum(map(lambda item: [0,
    sum(map(lambda col: [0,
      mx.__setitem__((item[0], col), value)
    ][0], item[1]))
  ][0], indices))
如果打印
a

[[2, 2, 2], [2, 2, 2], [2, 2, 2]]
编辑:案例2:使用
map()


我不太习惯这个。但是你可以在性能方面找到更多关于它的信息。总体思路:如果只使用一个函数而不使用lambda表达式,则速度会更快。

您必须使用for循环

通常,在遵循函数范式时,您希望通过构建新实例而不是修改旧实例来避免for循环(通过使用压缩)。由于您的目标是对旧的进行变异,因此在某些地方您将需要一个循环。您所能做的最好是将其封装在函数中:

def set_items_to(mx, indices, value=0):
  for row,cols in indices:
    for col in cols:
      mx[row, col] = value

a = matrix([[1,2,3],[4,5,6],[7,8,9]])
set_items_to(a, [
  [0, [0,1]],
  [1, [0,2]],
  [2, [1,2]]
], setvalue)
编辑

如果这是一个编程挑战,那么可以通过使用一个内置聚合器函数在没有显式for循环的情况下实现。但这种方法并不能使代码更清晰、更短。为了完整起见,它看起来是这样的:

value = 2
col_length = 3
line_length = 3
a = [[value for x in range(col_length)] for x in range(line_length)]
def set_items_to(mx, indices, value=0):
  sum(map(lambda item: [0,
    sum(map(lambda col: [0,
      mx.__setitem__((item[0], col), value)
    ][0], item[1]))
  ][0], indices))

使用
numpy
,可以避免循环:

import numpy as np
from numpy.matlib import repmat

a = np.array([[1,2,3],
              [8,2,9],
              [1,8,7]])

row = np.array([[1],
                [2],
                [3]])

col = np.array([[1,2],
                [1,3],
                [2,3]])

row = repmat(row,1,col.shape[1])

setvalue = 0
a[row.ravel(),col.ravel()] = setvalue
然而需要注意的是,在python中,索引从
0开始,所以实际上应该这样做

a[row-1,col-1] = setvalue

或者更好的方法是,使用正确的(基于零的)索引来初始化
数组。

我想编辑旧矩阵,而不是构建新矩阵。此方法仍然使用for循环。如果矩阵非常大,例如1000000*100000。如何保持相同的内存和运行时间?列表理解(内部
for
)比标准
for
循环快。但我会编辑我的帖子,“没有循环”。你的意思是在python中没有循环,在代码的使用中没有循环,还有别的吗?在某个地方需要有一个循环,即使它深入到解释器的内部,比如列表初始值设定项语法。我正在设想一个定制的python类
matrix
,您可以使用方法
matrix.setValue(行、列、值)
。这需要在matrix类内部进行循环,但不需要在方法的使用方式上进行循环。@AmiTavory a只是一个矩阵,其条目可以是int或float。@johncarcenter谢谢!是的,我指的是python代码中的循环。我认为解释器中深层的循环应该比代码中使用的循环快。谢谢。我已经尝试过这种方法,但花费的时间与for-loop方法几乎相同。对于132860*132860矩阵,将13行和132835列设置为零,您的方法花费7秒,for-loop方法花费6秒。@Matthew当您使用
ravel()
而不是
flatte()
时,速度会提高吗?我刚刚意识到,
ravel()
在创建副本时可以在适当的位置工作。