有没有什么办法可以让这么长的if语句变得更简洁呢?
Is there any way to make this long if statement more concise?
这是我的长 if 语句:
if i % 2 == 1 or i == 0:
if x1 > x:
ny = y + ceil(shift * (i / 2))
ny1 = y1 + ceil(shift * (i / 2))
elif x1 == x:
ny = y
ny1 = y1
elif x1 < x:
ny = y - ceil(shift * (i / 2))
ny1 = y1 - ceil(shift * (i / 2))
if y1 > y:
nx = x - ceil(shift * (i / 2))
nx1 = x1 - ceil(shift * (i / 2))
elif y1 == y:
nx = x
nx1 = x1
elif y1 < y:
nx = x + ceil(shift * (i / 2))
nx1 = x1 + ceil(shift * (i / 2))
else:
if x1 > x:
ny = y - ceil(shift * (i / 2))
ny1 = y1 - ceil(shift * (i / 2))
elif x1 == x:
ny = y
ny1 = y1
elif x1 < x:
ny = y + ceil(shift * (i / 2))
ny1 = y1 + ceil(shift * (i / 2))
if y1 > y:
nx = x + ceil(shift * (i / 2))
nx1 = x1 + ceil(shift * (i / 2))
elif y1 == y:
nx = x
nx1 = x1
elif y1 < y:
nx = x - ceil(shift * (i / 2))
nx1 = x1 - ceil(shift * (i / 2))
return nx, ny, nx1, ny1
我不确定是否可以将整个事情转换成一个简单的方程式。但是,如果没有,是否有任何可能的方法只使用第一个大 if 语句并使 ny = y + ceil(shift * (i / 2))
中的符号为正 if i % 2 == 1 or i == 0
和负 else
?
This guy 是你的朋友。比较主要的 if
和它的 else
,我们会看到:
这意味着只有天花板标志在分支之间发生变化。我们可以通过添加一个新变量来解决这个问题:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
if x1 > x:
ny = y + ceil_sign * ceil(shift * (i / 2))
ny1 = y1 + ceil_sign * ceil(shift * (i / 2))
elif x1 == x:
ny = y
ny1 = y1
elif x1 < x:
ny = y - ceil_sign * ceil(shift * (i / 2))
ny1 = y1 - ceil_sign * ceil(shift * (i / 2))
if y1 > y:
nx = x - ceil_sign * ceil(shift * (i / 2))
nx1 = x1 - ceil_sign * ceil(shift * (i / 2))
elif y1 == y:
nx = x
nx1 = x1
elif y1 < y:
nx = x + ceil_sign * ceil(shift * (i / 2))
nx1 = x1 + ceil_sign * ceil(shift * (i / 2))
您还可以移动分支:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
if x1 > x:
ny = y + ceil_sign * ceil(shift * (i / 2))
ny1 = y1 + ceil_sign * ceil(shift * (i / 2))
elif x1 < x:
ny = y - ceil_sign * ceil(shift * (i / 2))
ny1 = y1 - ceil_sign * ceil(shift * (i / 2))
else:
ny = y
ny1 = y1
if y1 > y:
nx = x - ceil_sign * ceil(shift * (i / 2))
nx1 = x1 - ceil_sign * ceil(shift * (i / 2))
elif y1 < y:
nx = x + ceil_sign * ceil(shift * (i / 2))
nx1 = x1 + ceil_sign * ceil(shift * (i / 2))
else:
nx = x
nx1 = x1
这次重构让我们看到了更多的差异:第一个 if
和它的 elif
也只改变了天花板标志。让我们添加另一个变量:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
if x1 == x:
ny = y
ny1 = y1
else:
x_ceil_sign = 1 if x1 > x else -1
ny = y + x_ceil_sign * ceil_sign * ceil(shift * (i / 2))
ny1 = y1 + x_ceil_sign * ceil_sign * ceil(shift * (i / 2))
if y1 == y:
nx = x
nx1 = x1
else:
y_ceil_sign = 1 if y1 < y else -1
nx = x + y_ceil_sign * ceil_sign * ceil(shift * (i / 2))
nx1 = x1 + y_ceil_sign * ceil_sign * ceil(shift * (i / 2))
正如@Barmar 所建议的,请注意 ceil_sign
总是与 ceil
调用一起出现。您可以将它们组合一次:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
ceil_value = ceil_sign * ceil(shift * (i / 2))
if x1 == x:
ny = y
ny1 = y1
else:
x_ceil_sign = 1 if x1 > x else -1
ny = y + x_ceil_sign * ceil_value
ny1 = y1 + x_ceil_sign * ceil_value
if y1 == y:
nx = x
nx1 = x1
else:
y_ceil_sign = 1 if y1 < y else -1
nx = x + y_ceil_sign * ceil_value
nx1 = x1 + y_ceil_sign * ceil_value
您可以对内部 ceil_sign
s 执行相同的移动:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
ceil_value = ceil_sign * ceil(shift * (i / 2))
if x1 == x:
ny = y
ny1 = y1
else:
x_ceil_sign = (1 if x1 > x else -1) * ceil_value
ny = y + x_ceil_sign
ny1 = y1 + x_ceil_sign
if y1 == y:
nx = x
nx1 = x1
else:
y_ceil_sign = (1 if y1 < y else -1) * ceil_value
nx = x + y_ceil_sign
nx1 = x1 + y_ceil_sign
请注意,在这两个子句中,您没有在 if
分支中添加任何内容,而在 else
分支中添加 *_ceil_sign
。创建另一个变量:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
ceil_value = ceil_sign * ceil(shift * (i / 2))
x_factor = 0 if x1 == x else ((1 if x1 > x else -1) * ceil_value)
ny = y + x_factor
ny1 = y1 + x_factor
y_factor = 0 if y1 == y else ((1 if y1 < y else -1) * ceil_value)
nx = x + y_factor
nx1 = x1 + y_factor
作为额外的重构,请注意如果 a > b,sign(a - b) 等于 1。您可以使用它来重构 *_factor
变量:
def sign(x):
return 0 if x == 0 else 1 if x > 0 else -1
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
ceil_value = ceil_sign * ceil(shift * (i / 2))
x_factor = 0 if x1 == x else sign(x1 - x) * ceil_value
ny = y + x_factor
ny1 = y1 + x_factor
y_factor = 0 if y1 == y else -sign(y1 - y) * ceil_value
nx = x + y_factor
nx1 = x1 + y_factor
另请注意,如果 a == b,则 sign(a - b) 等于 0,这同时定义了 *_factors
:
def sign(x):
return 0 if x == 0 else 1 if x > 0 else -1
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
ceil_value = ceil_sign * ceil(shift * (i / 2))
x_factor = sign(x1 - x) * ceil_value
ny = y + x_factor
ny1 = y1 + x_factor
y_factor = -sign(y1 - y) * ceil_value
nx = x + y_factor
nx1 = x1 + y_factor
这里有一些关于如何解决一般问题的提示:
- 查找经常重复的表达式,并命名它们。
在这里,ceil(shift * (i / 2))
经常发生。让我们命名为:
offset = ceil(shift * (i / 2))
if i % 2 == 1 or i == 0:
if x1 > x:
ny = y + offset
ny1 = y1 + offset
elif x1 == x:
ny = y
ny1 = y1
elif x1 < x:
ny = y - offset
ny1 = y1 - offset
if y1 > y:
nx = x - offset
nx1 = x1 - offset
elif y1 == y:
nx = x
nx1 = x1
elif y1 < y:
nx = x + offset
nx1 = x1 + offset
else:
if x1 > x:
ny = y - offset
ny1 = y1 - offset
elif x1 == x:
ny = y
ny1 = y1
elif x1 < x:
ny = y + offset
ny1 = y1 + offset
if y1 > y:
nx = x + offset
nx1 = x1 + offset
elif y1 == y:
nx = x
nx1 = x1
elif y1 < y:
nx = x - offset
nx1 = x1 - offset
return nx, ny, nx1, ny1
- 使用 Python 的 simultaneous assignment 对相关作业进行分组。
这很简单:
offset = ceil(shift * (i / 2))
if i % 2 == 1 or i == 0:
if x1 > x:
ny, ny1 = y + offset, y1 + offset
elif x1 == x:
ny, ny1 = y, y1
elif x1 < x:
ny, ny1 = y - offset, y1 - offset
if y1 > y:
nx, nx1 = x - offset, x1 - offset
elif y1 == y:
nx, nx1 = x, x1
elif y1 < y:
nx, nx1 = x + offset, x1 + offset
else:
if x1 > x:
ny, ny1 = y - offset, y1 - offset
elif x1 == x:
ny, ny1 = y, y1
elif x1 < x:
ny, ny1 = y + offset, y1 + offset
if y1 > y:
nx, nx1 = x + offset, x1 + offset
elif y1 == y:
nx, nx1 = x, x1
elif y1 < y:
nx, nx1 = x - offset, x1 - offset
return nx, ny, nx1, ny1
- 利用对称性和相似性。 (我对同步赋值 first 等简单语法进行调整的原因是,通过减少行数,我们可以使对称的事物在视觉上更接近,从而更容易注意到对称性。)
我所说的“对称”或“平行”的意思是我们用不同的变量做基本相同的事情(或者相关的事情有一些小的、有规律的改变)。这里有两个:首先,代码依赖 i % 2 == 1 or i == 0
的方式。我们可以很快看到这个效果 - 通过所有 if
/elif
逻辑传播 - 是当条件为假时,offset
被减去,否则它会被添加,并且反之亦然。我们可以使用初等代数来简化它,只需在不满足条件时将 offset
替换为 -offset
即可。因此:
offset = ceil(shift * (i / 2))
if not(i % 2 == 1 or i == 0):
offset = -offset
if x1 > x:
ny, ny1 = y + offset, y1 + offset
elif x1 == x:
ny, ny1 = y, y1
elif x1 < x:
ny, ny1 = y - offset, y1 - offset
if y1 > y:
nx, nx1 = x - offset, x1 - offset
elif y1 == y:
nx, nx1 = x, x1
elif y1 < y:
nx, nx1 = x + offset, x1 + offset
return nx, ny, nx1, ny1
- 进行代数化简。
模式识别在这里很有用。我们正在进行三向比较,并根据该比较添加、减去或不使用给定值。我们可以通过将 offset
分别乘以 1、-1 或 0 来表示“加、减或不使用”。如果我们提取那个想法:
def threeway_compare(a1, a):
if a1 > a:
return 1
elif a1 < a:
return -1
return 0 # a1 == a
然后我们找到隐藏的对称性(即我们做了两次那种三向比较):
offset = ceil(shift * (i / 2))
if not(i % 2 == 1 or i == 0):
offset = -offset
y_offset = threeway_compare(x1, x)
ny, ny1 = y + y_offset, y1 + y_offset
# Since the changes made to the nx/nx1 values were reversed,
# we negate the comparison result before using it this way.
x_offset = -threeway_compare(y1, y)
nx, nx1 = x + x_offset, x1 + x_offset
return nx, ny, nx1, ny1
- 舍弃一切,尝试不同的方法。
有时需要这样做。在这种特殊情况下,使用 ceil
来计算“调整”是出现问题的警告信号。直接计算 nx
等值可能更好,而不是计算 x
等然后必须以这种方式调整它们。也许这表明原始问题有问题。
这是我的长 if 语句:
if i % 2 == 1 or i == 0:
if x1 > x:
ny = y + ceil(shift * (i / 2))
ny1 = y1 + ceil(shift * (i / 2))
elif x1 == x:
ny = y
ny1 = y1
elif x1 < x:
ny = y - ceil(shift * (i / 2))
ny1 = y1 - ceil(shift * (i / 2))
if y1 > y:
nx = x - ceil(shift * (i / 2))
nx1 = x1 - ceil(shift * (i / 2))
elif y1 == y:
nx = x
nx1 = x1
elif y1 < y:
nx = x + ceil(shift * (i / 2))
nx1 = x1 + ceil(shift * (i / 2))
else:
if x1 > x:
ny = y - ceil(shift * (i / 2))
ny1 = y1 - ceil(shift * (i / 2))
elif x1 == x:
ny = y
ny1 = y1
elif x1 < x:
ny = y + ceil(shift * (i / 2))
ny1 = y1 + ceil(shift * (i / 2))
if y1 > y:
nx = x + ceil(shift * (i / 2))
nx1 = x1 + ceil(shift * (i / 2))
elif y1 == y:
nx = x
nx1 = x1
elif y1 < y:
nx = x - ceil(shift * (i / 2))
nx1 = x1 - ceil(shift * (i / 2))
return nx, ny, nx1, ny1
我不确定是否可以将整个事情转换成一个简单的方程式。但是,如果没有,是否有任何可能的方法只使用第一个大 if 语句并使 ny = y + ceil(shift * (i / 2))
中的符号为正 if i % 2 == 1 or i == 0
和负 else
?
This guy 是你的朋友。比较主要的 if
和它的 else
,我们会看到:
这意味着只有天花板标志在分支之间发生变化。我们可以通过添加一个新变量来解决这个问题:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
if x1 > x:
ny = y + ceil_sign * ceil(shift * (i / 2))
ny1 = y1 + ceil_sign * ceil(shift * (i / 2))
elif x1 == x:
ny = y
ny1 = y1
elif x1 < x:
ny = y - ceil_sign * ceil(shift * (i / 2))
ny1 = y1 - ceil_sign * ceil(shift * (i / 2))
if y1 > y:
nx = x - ceil_sign * ceil(shift * (i / 2))
nx1 = x1 - ceil_sign * ceil(shift * (i / 2))
elif y1 == y:
nx = x
nx1 = x1
elif y1 < y:
nx = x + ceil_sign * ceil(shift * (i / 2))
nx1 = x1 + ceil_sign * ceil(shift * (i / 2))
您还可以移动分支:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
if x1 > x:
ny = y + ceil_sign * ceil(shift * (i / 2))
ny1 = y1 + ceil_sign * ceil(shift * (i / 2))
elif x1 < x:
ny = y - ceil_sign * ceil(shift * (i / 2))
ny1 = y1 - ceil_sign * ceil(shift * (i / 2))
else:
ny = y
ny1 = y1
if y1 > y:
nx = x - ceil_sign * ceil(shift * (i / 2))
nx1 = x1 - ceil_sign * ceil(shift * (i / 2))
elif y1 < y:
nx = x + ceil_sign * ceil(shift * (i / 2))
nx1 = x1 + ceil_sign * ceil(shift * (i / 2))
else:
nx = x
nx1 = x1
这次重构让我们看到了更多的差异:第一个 if
和它的 elif
也只改变了天花板标志。让我们添加另一个变量:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
if x1 == x:
ny = y
ny1 = y1
else:
x_ceil_sign = 1 if x1 > x else -1
ny = y + x_ceil_sign * ceil_sign * ceil(shift * (i / 2))
ny1 = y1 + x_ceil_sign * ceil_sign * ceil(shift * (i / 2))
if y1 == y:
nx = x
nx1 = x1
else:
y_ceil_sign = 1 if y1 < y else -1
nx = x + y_ceil_sign * ceil_sign * ceil(shift * (i / 2))
nx1 = x1 + y_ceil_sign * ceil_sign * ceil(shift * (i / 2))
正如@Barmar 所建议的,请注意 ceil_sign
总是与 ceil
调用一起出现。您可以将它们组合一次:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
ceil_value = ceil_sign * ceil(shift * (i / 2))
if x1 == x:
ny = y
ny1 = y1
else:
x_ceil_sign = 1 if x1 > x else -1
ny = y + x_ceil_sign * ceil_value
ny1 = y1 + x_ceil_sign * ceil_value
if y1 == y:
nx = x
nx1 = x1
else:
y_ceil_sign = 1 if y1 < y else -1
nx = x + y_ceil_sign * ceil_value
nx1 = x1 + y_ceil_sign * ceil_value
您可以对内部 ceil_sign
s 执行相同的移动:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
ceil_value = ceil_sign * ceil(shift * (i / 2))
if x1 == x:
ny = y
ny1 = y1
else:
x_ceil_sign = (1 if x1 > x else -1) * ceil_value
ny = y + x_ceil_sign
ny1 = y1 + x_ceil_sign
if y1 == y:
nx = x
nx1 = x1
else:
y_ceil_sign = (1 if y1 < y else -1) * ceil_value
nx = x + y_ceil_sign
nx1 = x1 + y_ceil_sign
请注意,在这两个子句中,您没有在 if
分支中添加任何内容,而在 else
分支中添加 *_ceil_sign
。创建另一个变量:
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
ceil_value = ceil_sign * ceil(shift * (i / 2))
x_factor = 0 if x1 == x else ((1 if x1 > x else -1) * ceil_value)
ny = y + x_factor
ny1 = y1 + x_factor
y_factor = 0 if y1 == y else ((1 if y1 < y else -1) * ceil_value)
nx = x + y_factor
nx1 = x1 + y_factor
作为额外的重构,请注意如果 a > b,sign(a - b) 等于 1。您可以使用它来重构 *_factor
变量:
def sign(x):
return 0 if x == 0 else 1 if x > 0 else -1
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
ceil_value = ceil_sign * ceil(shift * (i / 2))
x_factor = 0 if x1 == x else sign(x1 - x) * ceil_value
ny = y + x_factor
ny1 = y1 + x_factor
y_factor = 0 if y1 == y else -sign(y1 - y) * ceil_value
nx = x + y_factor
nx1 = x1 + y_factor
另请注意,如果 a == b,则 sign(a - b) 等于 0,这同时定义了 *_factors
:
def sign(x):
return 0 if x == 0 else 1 if x > 0 else -1
ceil_sign = 1 if i % 2 == 1 or i == 0 else -1
ceil_value = ceil_sign * ceil(shift * (i / 2))
x_factor = sign(x1 - x) * ceil_value
ny = y + x_factor
ny1 = y1 + x_factor
y_factor = -sign(y1 - y) * ceil_value
nx = x + y_factor
nx1 = x1 + y_factor
这里有一些关于如何解决一般问题的提示:
- 查找经常重复的表达式,并命名它们。
在这里,ceil(shift * (i / 2))
经常发生。让我们命名为:
offset = ceil(shift * (i / 2))
if i % 2 == 1 or i == 0:
if x1 > x:
ny = y + offset
ny1 = y1 + offset
elif x1 == x:
ny = y
ny1 = y1
elif x1 < x:
ny = y - offset
ny1 = y1 - offset
if y1 > y:
nx = x - offset
nx1 = x1 - offset
elif y1 == y:
nx = x
nx1 = x1
elif y1 < y:
nx = x + offset
nx1 = x1 + offset
else:
if x1 > x:
ny = y - offset
ny1 = y1 - offset
elif x1 == x:
ny = y
ny1 = y1
elif x1 < x:
ny = y + offset
ny1 = y1 + offset
if y1 > y:
nx = x + offset
nx1 = x1 + offset
elif y1 == y:
nx = x
nx1 = x1
elif y1 < y:
nx = x - offset
nx1 = x1 - offset
return nx, ny, nx1, ny1
- 使用 Python 的 simultaneous assignment 对相关作业进行分组。
这很简单:
offset = ceil(shift * (i / 2))
if i % 2 == 1 or i == 0:
if x1 > x:
ny, ny1 = y + offset, y1 + offset
elif x1 == x:
ny, ny1 = y, y1
elif x1 < x:
ny, ny1 = y - offset, y1 - offset
if y1 > y:
nx, nx1 = x - offset, x1 - offset
elif y1 == y:
nx, nx1 = x, x1
elif y1 < y:
nx, nx1 = x + offset, x1 + offset
else:
if x1 > x:
ny, ny1 = y - offset, y1 - offset
elif x1 == x:
ny, ny1 = y, y1
elif x1 < x:
ny, ny1 = y + offset, y1 + offset
if y1 > y:
nx, nx1 = x + offset, x1 + offset
elif y1 == y:
nx, nx1 = x, x1
elif y1 < y:
nx, nx1 = x - offset, x1 - offset
return nx, ny, nx1, ny1
- 利用对称性和相似性。 (我对同步赋值 first 等简单语法进行调整的原因是,通过减少行数,我们可以使对称的事物在视觉上更接近,从而更容易注意到对称性。)
我所说的“对称”或“平行”的意思是我们用不同的变量做基本相同的事情(或者相关的事情有一些小的、有规律的改变)。这里有两个:首先,代码依赖 i % 2 == 1 or i == 0
的方式。我们可以很快看到这个效果 - 通过所有 if
/elif
逻辑传播 - 是当条件为假时,offset
被减去,否则它会被添加,并且反之亦然。我们可以使用初等代数来简化它,只需在不满足条件时将 offset
替换为 -offset
即可。因此:
offset = ceil(shift * (i / 2))
if not(i % 2 == 1 or i == 0):
offset = -offset
if x1 > x:
ny, ny1 = y + offset, y1 + offset
elif x1 == x:
ny, ny1 = y, y1
elif x1 < x:
ny, ny1 = y - offset, y1 - offset
if y1 > y:
nx, nx1 = x - offset, x1 - offset
elif y1 == y:
nx, nx1 = x, x1
elif y1 < y:
nx, nx1 = x + offset, x1 + offset
return nx, ny, nx1, ny1
- 进行代数化简。
模式识别在这里很有用。我们正在进行三向比较,并根据该比较添加、减去或不使用给定值。我们可以通过将 offset
分别乘以 1、-1 或 0 来表示“加、减或不使用”。如果我们提取那个想法:
def threeway_compare(a1, a):
if a1 > a:
return 1
elif a1 < a:
return -1
return 0 # a1 == a
然后我们找到隐藏的对称性(即我们做了两次那种三向比较):
offset = ceil(shift * (i / 2))
if not(i % 2 == 1 or i == 0):
offset = -offset
y_offset = threeway_compare(x1, x)
ny, ny1 = y + y_offset, y1 + y_offset
# Since the changes made to the nx/nx1 values were reversed,
# we negate the comparison result before using it this way.
x_offset = -threeway_compare(y1, y)
nx, nx1 = x + x_offset, x1 + x_offset
return nx, ny, nx1, ny1
- 舍弃一切,尝试不同的方法。
有时需要这样做。在这种特殊情况下,使用 ceil
来计算“调整”是出现问题的警告信号。直接计算 nx
等值可能更好,而不是计算 x
等然后必须以这种方式调整它们。也许这表明原始问题有问题。