嵌套条件语句的可读性
Readability in nested conditional statements
我目前正在 Python 中编写一个程序来模拟射影几何,射影点的同余函数看起来很糟糕。
(对于任何感兴趣的人,如果两个投影点都位于一条通过原点的直线上,则它们是全等的。)
class Point(object):
def __init__(self, a, b, c):
self.coords = [ a, b, c ]
def congruent(self, other):
ratio = 0
for i in range(3):
if self.coords[i] != 0 and other.coords[i] != 0:
if ratio is 0:
ratio = other.coords[i] / self.coords[i]
elif ratio != other.coords[i] / self.coords[i]:
return False
elif self.coords[i] != 0 or other.coords[i] != 0:
return False
return True
我是 Python 的新手,但我知道通常有一种 "Pythonic" 方法可以完成所有操作。考虑到这一点,我将如何使它更具可读性?
也许使用if self.coords[i]
代替if self.coords[i] != 0
(类似的例子也是如此)和if not ratio
代替if ratio is 0
。在Python中,任何非零值都通过if
子句,所以你不需要检查它是否非零,它是自动的。
def congurent(self,other):
ratio = None
for a,b in zip(self,other):
if a != 0 and b != 0:
if ratio is None:
ratio = a/float(b)
elif abs(ratio - a/float(b))>0.001:
return False
elif a!=0 or b!=0:
return False
return True
可能更像 pythonic...尽管它真正改变的是你如何遍历列表(它的行数相同)
这个怎么样:
def congruent(self, other, eps=0.001):
ratios = (c1 / c2 for c1, c2 in zip(self.coords, other.coords) if c1 or c2)
try:
first = next(ratios)
return all(abs(ratio - first) < eps for ratio in ratios)
except ZeroDivisionError:
return False
- 尽可能直接在元素上操作而不是在索引上操作(
zip
很方便)。
- 对于 任一 坐标不为零的情况,列表理解会获取所有坐标比率。如果两者都是,那很好,它被排除在外。
- ZDE 仅在
c1
为非零且 c2
为零时发生,因此失败。
- 最后,如果所有比率都相等,我们通过。
注意:如果您没有使用 Python 3,您应该将 from __future__ import division
添加到文件的顶部,这样您就不会得到不正确的整数坐标值结果。
编辑: 根据@JoranBeasley 添加了浮动比率的短路和 epsilon 比较。
我目前正在 Python 中编写一个程序来模拟射影几何,射影点的同余函数看起来很糟糕。
(对于任何感兴趣的人,如果两个投影点都位于一条通过原点的直线上,则它们是全等的。)
class Point(object):
def __init__(self, a, b, c):
self.coords = [ a, b, c ]
def congruent(self, other):
ratio = 0
for i in range(3):
if self.coords[i] != 0 and other.coords[i] != 0:
if ratio is 0:
ratio = other.coords[i] / self.coords[i]
elif ratio != other.coords[i] / self.coords[i]:
return False
elif self.coords[i] != 0 or other.coords[i] != 0:
return False
return True
我是 Python 的新手,但我知道通常有一种 "Pythonic" 方法可以完成所有操作。考虑到这一点,我将如何使它更具可读性?
也许使用if self.coords[i]
代替if self.coords[i] != 0
(类似的例子也是如此)和if not ratio
代替if ratio is 0
。在Python中,任何非零值都通过if
子句,所以你不需要检查它是否非零,它是自动的。
def congurent(self,other):
ratio = None
for a,b in zip(self,other):
if a != 0 and b != 0:
if ratio is None:
ratio = a/float(b)
elif abs(ratio - a/float(b))>0.001:
return False
elif a!=0 or b!=0:
return False
return True
可能更像 pythonic...尽管它真正改变的是你如何遍历列表(它的行数相同)
这个怎么样:
def congruent(self, other, eps=0.001):
ratios = (c1 / c2 for c1, c2 in zip(self.coords, other.coords) if c1 or c2)
try:
first = next(ratios)
return all(abs(ratio - first) < eps for ratio in ratios)
except ZeroDivisionError:
return False
- 尽可能直接在元素上操作而不是在索引上操作(
zip
很方便)。 - 对于 任一 坐标不为零的情况,列表理解会获取所有坐标比率。如果两者都是,那很好,它被排除在外。
- ZDE 仅在
c1
为非零且c2
为零时发生,因此失败。 - 最后,如果所有比率都相等,我们通过。
注意:如果您没有使用 Python 3,您应该将 from __future__ import division
添加到文件的顶部,这样您就不会得到不正确的整数坐标值结果。
编辑: 根据@JoranBeasley 添加了浮动比率的短路和 epsilon 比较。