在python中结合max、xrange和lambda函数的使用

时间:2022-03-29 20:10:40

I have found a code that pivotize a square matrix for LU decomposition, but I can't understand some of them.

我找到了一段代码,它以一个方阵为中心进行LU分解,但是我不能理解其中的一些。

def pivotize(m):
    """Creates the pivoting matrix for m."""
    n = len(m)
    ID = [[float(i == j) for i in xrange(n)] for j in xrange(n)]
    for j in xrange(n):
        row = max(xrange(j, n), key=lambda i: abs(m[i][j]))
        if j != row:
            ID[j], ID[row] = ID[row], ID[j]
    return ID

First, isn't the line for ID simply the identity matrix? any advantage doing this?

首先,ID的直线不是简单的单位矩阵吗?优势这么做吗?

Second, I can't really understand the line for row. I know lambda is used to define a function in the text, and it simply returns the value of M_ij once the value of i is supplied (and the value of j depends on the for loop), but what is i?

第二,我不能真正理解行。我知道lambda在文本中定义一个函数,它只是在提供I的值之后返回M_ij的值(j的值取决于for循环),但是I是什么呢?

And isn't xrange similar to range? But what does it return here?

xrange和range不是很相似吗?但是它返回了什么呢?

And when combined with the function max, what happens? I just don't know what are the things inside the max function that are being compared.

当与函数max结合时,会发生什么?我只是不知道在max函数中被比较的是什么。

Sorry if this question sounds stupid. I'm pretty new to programming

抱歉,如果这个问题听起来很愚蠢。我对编程很陌生

2 个解决方案

#1


3  

First, isn't the line for ID simply the identity matrix?

首先,ID的直线不是简单的单位矩阵吗?

Yes.

是的。

Second, I can't really understand the line for row....

第二,我不能真正理解为行....

See this for a discussion about the max/key/lambda interaction. To answer "what is i?", its the argument to the lambda function, i could equivalently be x for foo. (For clarity, yielding abs(m[x][j]) and abs(m[foo][j]), respectively).

有关max/key/lambda交互的讨论,请参见本文。回答“我是什么?”它是函数的参数,i可以等价地等于x。(为了清晰,分别生成abs(m[x][j])和abs(m[foo][j])。

And isn't xrange similar to range?

xrange和range不是很相似吗?

Yes. In Python 2 xrange returns a sequence object that lazily computes the next value, only when needed. See this for more info. When looped through in entirety, range and xrange will produce the same results, with different implementations.

是的。在Python 2 xrange中,返回一个序列对象,该对象只在需要时延迟计算下一个值。更多信息见此。当整个循环时,range和xrange将产生相同的结果,并具有不同的实现。

But what does it return here?

但是它返回了什么呢?

Line 5's xrange(n) will return the integer values from 0 to (n-1) while Line 6's xrange(j, n) will return the integer values from j to (n-1).

第5行的xrange(n)将返回从0到(n-1)的整数值,而第6行的xrange(j, n)将返回从j到(n-1)的整数值。

EDIT

编辑

More on lambda:

更多关于λ:

Consider how you might take a given sequence of numbers, and double each of them. First define a function that doubles a number x and returns that value. Then map that function to each element of a sequence.

考虑如何取一个给定的数字序列,并将它们加倍。首先定义一个函数,使数字x加倍并返回该值。然后将该函数映射到序列的每个元素。

# Traditional
def double(x): return x*2
print map(double, [1,2,3,4])         # [2, 4, 6, 8]

You could have alternatively used an anonymous (lambda) function to do the same thing:

您也可以使用匿名(lambda)函数来执行相同的操作:

# Lambda
print map(lambda i: i*2, [1,2,3,4])  # [2, 4, 6, 8]

Note that everything is the same, except the definition of the double function is gone and the reference to the function in the call to map is replaced by the "inline" lambda function.

注意,所有的东西都是相同的,除了双函数的定义没有了,而且调用映射中的函数的引用被“内联”lambda函数所替代。

EDIT 2

编辑2

And when combined with the function max, what happens?

当与函数max结合时,会发生什么?

This line row = max(xrange(j, n), key=lambda i: abs(m[i][j])) can be broken down as follows:

这一行= max(xrange(j, n), key= i: abs(m[i][j]))可细分如下:

  • xrange(j,n) generates a sequence of integers from j (inclusive) to n (exclusive).
  • xrange(j,n)生成一个从j(包括)到n(排除)的整数序列。
  • Each of those integers are then "passed" as arguments to the function in the key argument. In other words, they're each used as the i in the lambda function. The lambda function "returns" the absolute value of the ith row and jth column.[1]
  • 然后将这些整数中的每一个作为参数“传递”给键参数中的函数。换句话说,它们都被用作函数中的i。lambda函数“返回”第i行和第j列的绝对值[1]。
  • The max function then finds the greatest value of these "lambda outputs" and sets row equal to it.
  • max函数然后找到这些“lambda输出”的最大值,并将行设置为它。

This could have alternatively been written as a max of a list comprehension:

这也可以作为列表理解的最大值来写:

row = max( [abs(m[i][j]) for i in xrange(j,n)] )

Or as Dan D. points out in his comment, written as a generator expression (without creating an intermediary list) as simply:

或者像Dan D.在他的评论中指出的那样,作为一个生成器表达式(不创建一个中间列表)写成简单的:

row = max( abs(m[i][j]) for i in xrange(j,n) )

Notes:

注:

[1] Some assumptions here, but row-column is a standard way of expressing matrices.

这里有一些假设,但是行列是表示矩阵的标准方法。

#2


2  

xrange is an Python2 construct that's used for handling range memory efficient. Beforerange actually created a list, and then for loop would run through it. xrange however is a generator, that means it spits out 1 value at a time when it's asked to, without creating a full list.

xrange是一个Python2构造,用于高效地处理范围内存。Beforerange实际上创建了一个列表,然后for循环将在其中运行。然而xrange是一个生成器,这意味着它在被请求时每次输出1个值,而不创建完整的列表。

ID is actually an identity matrix. You're right there. That's a neat trick that boolean can be converted to float of value 1.0.

ID实际上是一个单位矩阵。你是对的。这是布尔值可以转换为浮点值1.0的巧妙技巧。

Then the snippet runs through all the remaining rows and finds the maximum value of that row in the original matrix row = max(xrange(j, n), key=lambda i: abs(m[i][j])). Notice that there's a 2nd nice trick in there, max can take any iterable object to operate on, including generators. lambda keyword in that row indicates what's known as "anonymous function".

然后,代码片段遍历所有剩余的行,并在原始矩阵行= max(xrange(j, n), key= i: abs(m[i][j])中找到该行的最大值。注意,这里有第二个很好的技巧,max可以对任何可迭代的对象进行操作,包括生成器。该行中的lambda关键字指示所谓的“匿名函数”。

In more details: Anonymous functions are functions that are not bound to an identifier. Lambda function in your snippet takes in 1 value, i and returns an absolute value at matrix position m[i][j]. The values that get sent as the input for the function are provided by the generator xrange(j, n).

更详细地说:匿名函数是不绑定到标识符的函数。在你的代码片段中,Lambda函数接受一个值i并返回一个在矩阵位置m[i][j]处的绝对值。作为函数的输入发送的值由生成器xrange(j, n)提供。

max then takes the return values of the lambda function as the thing it actually compares. In example, in python3 it's not possible to compare 2 different types. I.e. comparing string > int produces: TypeError: unorderable types: str() > int(). However if we're sure that the list contains numbers, just in different format, you can do something like:

max取函数的返回值作为它实际比较的值。例如,在python3中不可能比较两种不同的类型。即比较字符串> int产生:TypeError:无序类型:str() > int()但是,如果我们确定列表包含数字,只是格式不同,您可以做以下事情:

>>> l = ["1", "2", 3, 4]
>>> max(l, key=lambda x: int(x))
4
>>> min(l, key=lambda x: int(x))
'1' #type 'str'

This just shows, that the actual compared values are the returns of your key function, but actual produced values are your original input values.

这只表明,实际比较值是键函数的返回值,而实际生成的值是原始输入值。

Once it found the rows maximum value, it "rotates", by substitution ID[j], ID[row] = ID[row], ID[j], all the other rows, in the identity matrix, around it so that only the maximum value remains on the diagonal.

一旦它找到了行最大值,它就会“旋转”,通过替换ID[j], ID[row] = ID[row], ID[j],所有其他的行,在单位矩阵中,围绕它旋转,使得只有最大值保持在对角线上。

This helps prevent division by a too small a number in the next step of LU decomposition.

这有助于防止在LU分解的下一个步骤中以一个太小的数字进行划分。

What you get in return, isn't the original matrix, rotated, but a matrix of 1.0s and 0.0s that is your transformation matrix that multiplied by the original one will result in the pivoted matrix.

你得到的回报,不是原来的矩阵,旋转了,而是1。0和0。0的矩阵这是你的变换矩阵乘以原来的矩阵会得到旋转矩阵。

This seems a very nicely written function that saves memory and helps performance in python. Hopefully I did this right.

这似乎是一个编写得很好的函数,可以节省内存,并有助于在python中提高性能。希望我做对了。

#1


3  

First, isn't the line for ID simply the identity matrix?

首先,ID的直线不是简单的单位矩阵吗?

Yes.

是的。

Second, I can't really understand the line for row....

第二,我不能真正理解为行....

See this for a discussion about the max/key/lambda interaction. To answer "what is i?", its the argument to the lambda function, i could equivalently be x for foo. (For clarity, yielding abs(m[x][j]) and abs(m[foo][j]), respectively).

有关max/key/lambda交互的讨论,请参见本文。回答“我是什么?”它是函数的参数,i可以等价地等于x。(为了清晰,分别生成abs(m[x][j])和abs(m[foo][j])。

And isn't xrange similar to range?

xrange和range不是很相似吗?

Yes. In Python 2 xrange returns a sequence object that lazily computes the next value, only when needed. See this for more info. When looped through in entirety, range and xrange will produce the same results, with different implementations.

是的。在Python 2 xrange中,返回一个序列对象,该对象只在需要时延迟计算下一个值。更多信息见此。当整个循环时,range和xrange将产生相同的结果,并具有不同的实现。

But what does it return here?

但是它返回了什么呢?

Line 5's xrange(n) will return the integer values from 0 to (n-1) while Line 6's xrange(j, n) will return the integer values from j to (n-1).

第5行的xrange(n)将返回从0到(n-1)的整数值,而第6行的xrange(j, n)将返回从j到(n-1)的整数值。

EDIT

编辑

More on lambda:

更多关于λ:

Consider how you might take a given sequence of numbers, and double each of them. First define a function that doubles a number x and returns that value. Then map that function to each element of a sequence.

考虑如何取一个给定的数字序列,并将它们加倍。首先定义一个函数,使数字x加倍并返回该值。然后将该函数映射到序列的每个元素。

# Traditional
def double(x): return x*2
print map(double, [1,2,3,4])         # [2, 4, 6, 8]

You could have alternatively used an anonymous (lambda) function to do the same thing:

您也可以使用匿名(lambda)函数来执行相同的操作:

# Lambda
print map(lambda i: i*2, [1,2,3,4])  # [2, 4, 6, 8]

Note that everything is the same, except the definition of the double function is gone and the reference to the function in the call to map is replaced by the "inline" lambda function.

注意,所有的东西都是相同的,除了双函数的定义没有了,而且调用映射中的函数的引用被“内联”lambda函数所替代。

EDIT 2

编辑2

And when combined with the function max, what happens?

当与函数max结合时,会发生什么?

This line row = max(xrange(j, n), key=lambda i: abs(m[i][j])) can be broken down as follows:

这一行= max(xrange(j, n), key= i: abs(m[i][j]))可细分如下:

  • xrange(j,n) generates a sequence of integers from j (inclusive) to n (exclusive).
  • xrange(j,n)生成一个从j(包括)到n(排除)的整数序列。
  • Each of those integers are then "passed" as arguments to the function in the key argument. In other words, they're each used as the i in the lambda function. The lambda function "returns" the absolute value of the ith row and jth column.[1]
  • 然后将这些整数中的每一个作为参数“传递”给键参数中的函数。换句话说,它们都被用作函数中的i。lambda函数“返回”第i行和第j列的绝对值[1]。
  • The max function then finds the greatest value of these "lambda outputs" and sets row equal to it.
  • max函数然后找到这些“lambda输出”的最大值,并将行设置为它。

This could have alternatively been written as a max of a list comprehension:

这也可以作为列表理解的最大值来写:

row = max( [abs(m[i][j]) for i in xrange(j,n)] )

Or as Dan D. points out in his comment, written as a generator expression (without creating an intermediary list) as simply:

或者像Dan D.在他的评论中指出的那样,作为一个生成器表达式(不创建一个中间列表)写成简单的:

row = max( abs(m[i][j]) for i in xrange(j,n) )

Notes:

注:

[1] Some assumptions here, but row-column is a standard way of expressing matrices.

这里有一些假设,但是行列是表示矩阵的标准方法。

#2


2  

xrange is an Python2 construct that's used for handling range memory efficient. Beforerange actually created a list, and then for loop would run through it. xrange however is a generator, that means it spits out 1 value at a time when it's asked to, without creating a full list.

xrange是一个Python2构造,用于高效地处理范围内存。Beforerange实际上创建了一个列表,然后for循环将在其中运行。然而xrange是一个生成器,这意味着它在被请求时每次输出1个值,而不创建完整的列表。

ID is actually an identity matrix. You're right there. That's a neat trick that boolean can be converted to float of value 1.0.

ID实际上是一个单位矩阵。你是对的。这是布尔值可以转换为浮点值1.0的巧妙技巧。

Then the snippet runs through all the remaining rows and finds the maximum value of that row in the original matrix row = max(xrange(j, n), key=lambda i: abs(m[i][j])). Notice that there's a 2nd nice trick in there, max can take any iterable object to operate on, including generators. lambda keyword in that row indicates what's known as "anonymous function".

然后,代码片段遍历所有剩余的行,并在原始矩阵行= max(xrange(j, n), key= i: abs(m[i][j])中找到该行的最大值。注意,这里有第二个很好的技巧,max可以对任何可迭代的对象进行操作,包括生成器。该行中的lambda关键字指示所谓的“匿名函数”。

In more details: Anonymous functions are functions that are not bound to an identifier. Lambda function in your snippet takes in 1 value, i and returns an absolute value at matrix position m[i][j]. The values that get sent as the input for the function are provided by the generator xrange(j, n).

更详细地说:匿名函数是不绑定到标识符的函数。在你的代码片段中,Lambda函数接受一个值i并返回一个在矩阵位置m[i][j]处的绝对值。作为函数的输入发送的值由生成器xrange(j, n)提供。

max then takes the return values of the lambda function as the thing it actually compares. In example, in python3 it's not possible to compare 2 different types. I.e. comparing string > int produces: TypeError: unorderable types: str() > int(). However if we're sure that the list contains numbers, just in different format, you can do something like:

max取函数的返回值作为它实际比较的值。例如,在python3中不可能比较两种不同的类型。即比较字符串> int产生:TypeError:无序类型:str() > int()但是,如果我们确定列表包含数字,只是格式不同,您可以做以下事情:

>>> l = ["1", "2", 3, 4]
>>> max(l, key=lambda x: int(x))
4
>>> min(l, key=lambda x: int(x))
'1' #type 'str'

This just shows, that the actual compared values are the returns of your key function, but actual produced values are your original input values.

这只表明,实际比较值是键函数的返回值,而实际生成的值是原始输入值。

Once it found the rows maximum value, it "rotates", by substitution ID[j], ID[row] = ID[row], ID[j], all the other rows, in the identity matrix, around it so that only the maximum value remains on the diagonal.

一旦它找到了行最大值,它就会“旋转”,通过替换ID[j], ID[row] = ID[row], ID[j],所有其他的行,在单位矩阵中,围绕它旋转,使得只有最大值保持在对角线上。

This helps prevent division by a too small a number in the next step of LU decomposition.

这有助于防止在LU分解的下一个步骤中以一个太小的数字进行划分。

What you get in return, isn't the original matrix, rotated, but a matrix of 1.0s and 0.0s that is your transformation matrix that multiplied by the original one will result in the pivoted matrix.

你得到的回报,不是原来的矩阵,旋转了,而是1。0和0。0的矩阵这是你的变换矩阵乘以原来的矩阵会得到旋转矩阵。

This seems a very nicely written function that saves memory and helps performance in python. Hopefully I did this right.

这似乎是一个编写得很好的函数,可以节省内存,并有助于在python中提高性能。希望我做对了。