如何使这个循环成为单行? (列表理解)

问题描述 投票:0回答:1

我想把这段Python代码(循环)变成一行,但我不知道怎么做。

KE, ndof, K, F, U = KT, 2 * (nely + 1) * (nelx + 1), lil_matrix((2 * (nely + 1) * (nelx + 1), 2 * (nely + 1) * (nelx + 1))), zeros(2 * (nely + 1) * (nelx + 1)), zeros(2 * (nely + 1) * (nelx + 1))
    for ely in range(1,nely+1):
        for elx in range(1,nelx+1):
            K[np.ix_([2*((nely+1)*(elx-1)+ely)-2, 2*((nely+1)*(elx-1)+ely)-1, 2*((nely+1)*elx+ely)-2, 2*((nely+1)*elx+ely)-1, 2*((nely+1)*elx+ely), 2*((nely+1)*elx+ely)+1, 2*((nely+1)*(elx-1)+ely), 2*((nely+1)*(elx-1)+ely)+1],[2*((nely+1)*(elx-1)+ely)-2, 2*((nely+1)*(elx-1)+ely)-1, 2*((nely+1)*elx+ely)-2, 2*((nely+1)*elx+ely)-1, 2*((nely+1)*elx+ely), 2*((nely+1)*elx+ely)+1, 2*((nely+1)*(elx-1)+ely), 2*((nely+1)*(elx-1)+ely)+1])] += x[ely-1,elx-1]**penal * KE

在这种情况下也是同样的事情:

    dcn = zeros((nely, nelx))
    for i in range(nelx):
        for j in range(nely):
            dcn[j, i] = (dcn[j, i] + sum((rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5) * (rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5 > 0) * x[l, k] * dc[l, k] for k in range(int(max(i - round(rmin), 0)), int(min(i + round(rmin) + 1, nelx))) for l in range(int(max(j - round(rmin), 0)), int(min(j + round(rmin) + 1, nely))))) / (x[j, i] * ((sum((rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5) * (rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5 > 0) for k in range(int(max(i - round(rmin), 0)), int(min(i + round(rmin) + 1, nelx))) for l in range(int(max(j - round(rmin), 0)), int(min(j + round(rmin) + 1, nely)))))+((sum((rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5) * (rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5 > 0) for k in range(int(max(i - round(rmin), 0)), int(min(i + round(rmin) + 1, nelx))) for l in range(int(max(j - round(rmin), 0)), int(min(j + round(rmin) + 1, nely))))) == 0)))

我尝试使用列表理解和 np.sum,但它不起作用。另外,如果你们知道怎么做,我也需要制作一个在一行中包含这些循环的函数:

def check(nelx, nely, rmin, x, dc):
    dcn = zeros((nely, nelx))
    for i in range(nelx):
        for j in range(nely):
            dcn[j, i] = (dcn[j, i] + sum((rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5) * (rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5 > 0) * x[l, k] * dc[l, k] for k in range(int(max(i - round(rmin), 0)), int(min(i + round(rmin) + 1, nelx))) for l in range(int(max(j - round(rmin), 0)), int(min(j + round(rmin) + 1, nely))))) / (x[j, i] * ((sum((rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5) * (rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5 > 0) for k in range(int(max(i - round(rmin), 0)), int(min(i + round(rmin) + 1, nelx))) for l in range(int(max(j - round(rmin), 0)), int(min(j + round(rmin) + 1, nely)))))+((sum((rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5) * (rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5 > 0) for k in range(int(max(i - round(rmin), 0)), int(min(i + round(rmin) + 1, nelx))) for l in range(int(max(j - round(rmin), 0)), int(min(j + round(rmin) + 1, nely))))) == 0)))
    return dcn
python list numpy list-comprehension resume
1个回答
0
投票

当然你可以这样做:

def check2(nelx,nely,rmin,x,dc):return np.array([[((sum((rmin -((i-k)**2+(j-l)**2)**0.5)*(rmin -((i-k)**2+(j-l)**2)**0.5>0)*x[l,k]*dc[l,k] for k in range(int(max(i-round(rmin),0)),int(min(i+round(rmin)+1,nelx))) for l in range(int(max(j-round(rmin),0)),int(min(j+round(rmin)+1,nely)))))/(x[j,i]*((sum((rmin-((i-k)**2+(j-l)**2)**0.5)*(rmin-((i-k)**2+(j-l)**2)**0.5>0) for k in range(int(max(i-round(rmin),0)),int(min(i+round(rmin)+1,nelx))) for l in range(int(max(j-round(rmin),0)),int(min(j+round(rmin)+1,nely)))))+((sum((rmin-((i-k)**2+(j-l)**2)**0.5)*(rmin-((i-k)**2+(j-l)**2)**0.5>0) for k in range(int(max(i-round(rmin),0)),int(min(i+round(rmin)+1,nelx))) for l in range(int(max(j-round(rmin),0)),int(min(j+round(rmin)+1,nely)))))==0)))) for i in range(nelx)] for j in range(nely)])

您也可以尝试使用尽可能多的行:

def check3(
    nelx,
    nely,
    rmin,
    x,
    dc
):
    dcn = zeros(
        (
            nely,
            nelx
        )
    )
    for i in range(
        nelx
    ):
        for j in range(
            nely
        ):
            dcn[
                j,
                i
            ] = (
                dcn[
                    j,
                    i
                ] + sum(
                    (
                        rmin - (
                            (
                                i - k
                            ) ** 2 + (
                                j - l
                            ) ** 2
                        ) ** 0.5
                    ) * (
                        rmin - (
                            (
                                i - k
                            ) ** 2 + (
                                j - l
                            ) ** 2
                        ) ** 0.5 > 0
                    ) * x[
                        l,
                        k
                    ] * dc[
                        l,
                        k
                    ] for k in range(
                        int(
                            max(
                                i - round(
                                    rmin
                                ),
                                0
                            )
                        ),
                        int(
                            min(
                                i + round(
                                    rmin
                                ) + 1,
                                nelx
                            )
                        )
                    ) for l in range(
                        int(
                            max(
                                j - round(
                                    rmin
                                ),
                                0
                            )
                        ),
                        int(
                            min(
                                j + round(
                                    rmin
                                ) + 1,
                                nely
                            )
                        )
                    )
                )
            ) / (
                x[
                    j,
                    i
                ] * (
                    (
                        sum(
                            (
                                rmin - (
                                    (
                                        i - k
                                    ) ** 2 + (
                                        j - l
                                    ) ** 2
                                ) ** 0.5
                            ) * (
                                rmin - (
                                    (
                                        i - k
                                    ) ** 2 + (
                                        j - l
                                    ) ** 2
                                ) ** 0.5 > 0
                            ) for k in range(
                                int(
                                    max(
                                        i - round(
                                            rmin
                                        ),
                                        0
                                    )
                                ), int(
                                    min(
                                        i + round(
                                            rmin
                                        ) + 1,
                                        nelx
                                    )
                                )
                            ) for l in range(
                                int(
                                    max(
                                        j - round(
                                            rmin
                                        ),
                                        0
                                    )
                                ), int(
                                    min(
                                        j + round(
                                            rmin
                                        ) + 1,
                                        nely
                                    )
                                )
                            )
                        )
                    ) + (
                        (
                            sum(
                                (
                                    rmin - (
                                        (
                                            i - k
                                        ) ** 2 + (
                                            j - l
                                        ) ** 2
                                    ) ** 0.5
                                ) * (
                                    rmin - (
                                        (
                                            i - k
                                        ) ** 2 + (
                                            j - l
                                        ) ** 2
                                    ) ** 0.5 > 0
                                ) for k in range(
                                    int(
                                        max(
                                            i - round(
                                                rmin
                                            ), 0
                                        )
                                    ), int(
                                        min(
                                            i + round(
                                                rmin
                                            ) + 1,
                                            nelx
                                        )
                                    )
                                ) for l in range(
                                    int(
                                        max(
                                            j - round(
                                                rmin
                                            ),
                                            0
                                        )
                                    ), int(
                                        min(
                                            j + round(
                                                rmin
                                            ) + 1,
                                            nely
                                        )
                                    )
                                )
                            )
                        ) == 0
                    )
                )
            )
    return dcn

但是,如果您更关心代码的可读性和可维护性,以及可能还关心运行时效率(例如,如果您可以使用变量来避免多次计算相同的内容),而不是最小化或最大化代码的行数,代码,那么你可能最好选择介于两者之间的东西,正如其他人已经在评论中指出的那样;)

import numpy as np
zeros = np.zeros

def check(nelx, nely, rmin, x, dc):
    dcn = zeros((nely, nelx))
    for i in range(nelx):
        for j in range(nely):
            dcn[j, i] = (dcn[j, i] + sum((rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5) * (rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5 > 0) * x[l, k] * dc[l, k] for k in range(int(max(i - round(rmin), 0)), int(min(i + round(rmin) + 1, nelx))) for l in range(int(max(j - round(rmin), 0)), int(min(j + round(rmin) + 1, nely))))) / (x[j, i] * ((sum((rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5) * (rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5 > 0) for k in range(int(max(i - round(rmin), 0)), int(min(i + round(rmin) + 1, nelx))) for l in range(int(max(j - round(rmin), 0)), int(min(j + round(rmin) + 1, nely)))))+((sum((rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5) * (rmin - ((i - k) ** 2 + (j - l) ** 2) ** 0.5 > 0) for k in range(int(max(i - round(rmin), 0)), int(min(i + round(rmin) + 1, nelx))) for l in range(int(max(j - round(rmin), 0)), int(min(j + round(rmin) + 1, nely))))) == 0)))
    return dcn

for nelx in range(1, 5):
    for nely in range(1, 5):
        for rmin in range(1, 5):
            for k in range(10):
                a, b, c, d = np.random.randint(1, 10, 4)
                x = np.random.randint(1, 10, (a, b))
                dc = np.random.randint(1, 10, (c, d))
                passes = False
                try:
                    res = check(nelx, nely, rmin, x, dc)
                    assert np.isfinite(res).all()
                    passes = True
                except:
                    pass
                if passes:
                    assert np.array_equal(res, check2(nelx, nely, rmin, x, dc))
                    assert np.array_equal(res, check3(nelx, nely, rmin, x, dc))
© www.soinside.com 2019 - 2024. All rights reserved.