Python:避免嵌套的for循环

时间:2018-10-27 11:06:24

标签: python python-3.x for-loop map-function

如何避免以下代码中的嵌套for循环,而例如使用map函数?

import numpy as np

A = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
n = len(A[0])
B = np.zeros((n,n))

for i in range(n):
    for j in range(n):
        B[j,i] = min(A[:,i]/A[:,j])

1 个答案:

答案 0 :(得分:1)

我认为map()不适合解决此问题,因为您期望的结果是嵌套而不是拼合的。这比仅使用列表理解来获得所需的结果还要冗长一些。这是初始化B的一种更简洁的方法。

B = np.array([np.min(A.T/r, axis=1) for r in A.T])

此操作遍历A的每一列(A.T的每一行)并计算广播的除法A.T/r。 Numpy能够优化这一点,远远超出了原始循环所能做的。然后,np.min()的使用会比我们能够更快地计算出我们刚沿着行(由于参数axis=1而行而不是列)计算出的那个矩阵的最小值内置min()进行内部矢量化处理。

如果您确实想映射某些内容,@ MartijnPieters指出您可以将itertools与itertools.product(range(len(A[0])), repeat=2)配合使用以实现相同的索引对。否则,您可以使用生成器((r, s) for r in A.T for s in A.T)来获取成对的行而不是成对的索引。无论哪种情况,您都可以在可迭代的对象上应用map(),但是仍然必须以某种方式嵌套结果才能正确初始化B

注意:这可能不是您期望的结果。 A的元素默认情况下为整数(请注意,您使用的是3而不是3.)。当您将A的整数元素相除时,您将再次获得整数。在您的代码中,np.zeros()将这些整数强制转换为浮点数的事实使部分混淆,但是无论如何数学都是错误的。要解决此问题,请在构造A时传递一个附加参数:

A = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], float)