我想把这段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
当然你可以这样做:
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))