Python:可以交换数学运算符以避免代码重复吗?
Python: Possible to exchange math operators so as to avoid code duplication?
我有这个功能(见下文),看起来它会自己重复四次。这四个代码片段非常相似,它们只是在一些数学运算符上有所不同。是否可以缩短此代码?我找不到办法,但我希望能够调用一个函数(在函数中)交换代码片段中的“-”、“+”和“<”/“>”符号,这样我就可以不必重复?
代码
def diag_grannar(storlek,troll_position): #funktion som kollar efter diagonala grannar
ny_rad = troll_position[0]
ny_kol = troll_position[1]
diag_grannar = []
# while-loopen letar efter diagonala grannar snett vänster ovanifrån troll_position
while True:
ny_rad -= 1
ny_kol -= 1
if ny_rad >= 1 and ny_kol >= 1:
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
# while-loopen letar efter diagonala grannar snett vänster nedanifrån troll_position
while True:
ny_rad += 1
ny_kol -= 1
if ny_rad <= storlek and ny_kol >= 1:
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
# while-loopen letar efter diagonala grannar snett höger nedanifrån troll_position
while True:
ny_rad += 1
ny_kol += 1
if ny_rad <= storlek and ny_kol <= storlek:
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
# while-loopen letar efter diagonala grannar snett höger ovanifrån troll_position
while True:
ny_rad -= 1
ny_kol += 1
if ny_rad >= 1 and ny_kol <= storlek:
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
return diag_grannar
为了清楚起见,我指的是这些代码片段:
while True:
ny_rad -= 1
ny_kol += 1
if ny_rad >= 1 and ny_kol <= storlek:
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
此致;
让我们从彻底摆脱循环开始:
def diag_grannar(storlek,troll_position):
ny_rad = troll_position[0]
ny_kol = troll_position[1]
diag_grannar = []
diag_grannar.extend([x,y] for x, y in zip(range(ny_rad-1, 0, -1), range(ny_kol-1, 0, -1)))
diag_grannar.extend([x,y] for x, y in zip(range(ny_rad+1, storlek+1), range(ny_kol-1, 0, -1)))
diag_grannar.extend([x,y] for x, y in zip(range(ny_rad+1, storlek+1), range(ny_kol+1, storlek+1)))
diag_grannar.extend([x,y] for x, y in zip(range(ny_rad-1, 0, -1), range(ny_kol+1, storlek+1)))
return diag_grannar
现在我们可以根据需要尝试反转范围。 range(x-1, 0, -1)
等同于 reversed(range(1, x))
.
def diag_grannar(storlek,troll_position):
ny_rad = troll_position[0]
ny_kol = troll_position[1]
diag_grannar = []
xs = range(1, ny_rad + 1)
ys = range(1, ny_kol + 1)
diag_grannar.extend(list(t) for t in zip(reversed(xs), reversed(ys))
diag_grannar.extend(list(t) for t in zip(xs, reversed(ys))
diag_grannar.extend(list(t) for t in zip(xs, ys))
diag_grannar.extend(list(t) for t in zip(reversed(xs), ys))
return diag_grannar
我们可以遍历同一事物的各种参数化...需要注意的是,我们始终可以使用加法而不是交换数学运算符,只需添加 1 或 -1(比交换匹配运算符更容易)
def diag_grannar1(storlek,troll_position): #funktion som kollar efter diagonala grannar
ny_rad = troll_position[0]
ny_kol = troll_position[1]
diag_grannar = []
def diag_compare(v1, leq):
if leq:
return v1 <= storlek
else:
return v1 >= 1
params = [((-1, -1, False, False)),
((1, -1, True, False)),
((1, 1, True, True)),
((-1, 1, False, True))]
for v1, v2, leq1, leq2 in params:
while True:
ny_rad += v1
ny_kol += v2
if diag_compare(ny_rad, leq1) and diag_compare(ny_kol, leq2):
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
return diag_grannar
如果将重复的代码放在一个函数中,您可以将内置 operator
模块中的函数作为参数传入,然后使用它们。
我有这个功能(见下文),看起来它会自己重复四次。这四个代码片段非常相似,它们只是在一些数学运算符上有所不同。是否可以缩短此代码?我找不到办法,但我希望能够调用一个函数(在函数中)交换代码片段中的“-”、“+”和“<”/“>”符号,这样我就可以不必重复?
代码
def diag_grannar(storlek,troll_position): #funktion som kollar efter diagonala grannar
ny_rad = troll_position[0]
ny_kol = troll_position[1]
diag_grannar = []
# while-loopen letar efter diagonala grannar snett vänster ovanifrån troll_position
while True:
ny_rad -= 1
ny_kol -= 1
if ny_rad >= 1 and ny_kol >= 1:
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
# while-loopen letar efter diagonala grannar snett vänster nedanifrån troll_position
while True:
ny_rad += 1
ny_kol -= 1
if ny_rad <= storlek and ny_kol >= 1:
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
# while-loopen letar efter diagonala grannar snett höger nedanifrån troll_position
while True:
ny_rad += 1
ny_kol += 1
if ny_rad <= storlek and ny_kol <= storlek:
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
# while-loopen letar efter diagonala grannar snett höger ovanifrån troll_position
while True:
ny_rad -= 1
ny_kol += 1
if ny_rad >= 1 and ny_kol <= storlek:
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
return diag_grannar
为了清楚起见,我指的是这些代码片段:
while True:
ny_rad -= 1
ny_kol += 1
if ny_rad >= 1 and ny_kol <= storlek:
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
此致;
让我们从彻底摆脱循环开始:
def diag_grannar(storlek,troll_position):
ny_rad = troll_position[0]
ny_kol = troll_position[1]
diag_grannar = []
diag_grannar.extend([x,y] for x, y in zip(range(ny_rad-1, 0, -1), range(ny_kol-1, 0, -1)))
diag_grannar.extend([x,y] for x, y in zip(range(ny_rad+1, storlek+1), range(ny_kol-1, 0, -1)))
diag_grannar.extend([x,y] for x, y in zip(range(ny_rad+1, storlek+1), range(ny_kol+1, storlek+1)))
diag_grannar.extend([x,y] for x, y in zip(range(ny_rad-1, 0, -1), range(ny_kol+1, storlek+1)))
return diag_grannar
现在我们可以根据需要尝试反转范围。 range(x-1, 0, -1)
等同于 reversed(range(1, x))
.
def diag_grannar(storlek,troll_position):
ny_rad = troll_position[0]
ny_kol = troll_position[1]
diag_grannar = []
xs = range(1, ny_rad + 1)
ys = range(1, ny_kol + 1)
diag_grannar.extend(list(t) for t in zip(reversed(xs), reversed(ys))
diag_grannar.extend(list(t) for t in zip(xs, reversed(ys))
diag_grannar.extend(list(t) for t in zip(xs, ys))
diag_grannar.extend(list(t) for t in zip(reversed(xs), ys))
return diag_grannar
我们可以遍历同一事物的各种参数化...需要注意的是,我们始终可以使用加法而不是交换数学运算符,只需添加 1 或 -1(比交换匹配运算符更容易)
def diag_grannar1(storlek,troll_position): #funktion som kollar efter diagonala grannar
ny_rad = troll_position[0]
ny_kol = troll_position[1]
diag_grannar = []
def diag_compare(v1, leq):
if leq:
return v1 <= storlek
else:
return v1 >= 1
params = [((-1, -1, False, False)),
((1, -1, True, False)),
((1, 1, True, True)),
((-1, 1, False, True))]
for v1, v2, leq1, leq2 in params:
while True:
ny_rad += v1
ny_kol += v2
if diag_compare(ny_rad, leq1) and diag_compare(ny_kol, leq2):
diag_grannar.append([ny_rad,ny_kol])
else:
ny_rad = troll_position[0]
ny_kol = troll_position[1]
break
return diag_grannar
如果将重复的代码放在一个函数中,您可以将内置 operator
模块中的函数作为参数传入,然后使用它们。