整活:记一次 Python 压行的经历。
为什么我要写这篇文章?
- 众所周知,C++ 的所有非预处理可以压到一行,因为人家有分号。但是 Python 靠缩进!
- 本来想写一个一次函数计算器的,但是为了方便想压行。
- 前不久,我了解到 Python 海象运算符。起初觉得这和 C++ 的特性一样嘛,经常会在记忆化搜索等类似的算法中用到。然后在实战中应用了一下,就突然发掘出了 Python 压行的玩法。
警告:
压行是为了整活,有时可以帮助减少代码体积。但是这样做很可能降低代码可读性,而且极难调试!
尽量不要在开发使用这样的手段!
需求和推论
需求:平面直角坐标系内,给出两个不同的点 、,求直线 的表达式。
方法:待定系数法。
设 .
将 、 代入,得 .
所以 .
其他要求:
- 结果应该化成 的形式。
- 输入共两行,每行两个数,用空格隔开,分别表示 、 两点的横、纵坐标。输入可能为小数。
- 时,化为 的形式。
- 时,化为 的形式。
- 时,化为 的形式。
- 能化为整数的化为整数,不要有 、 等的数出现。
原始代码
_x1, _y1 = input("A >>> ").split()
_x2, _y2 = input("B >>> ").split()
x1, y1 = eval(_x1), eval(_y1)
x2, y2 = eval(_x2), eval(_y2)
k = (y2 - y1) / (x2 - x1)
b = y1 - k * x1
if int(k) == float(k):
k = int(k)
if int(b) == float(b):
b = int(b)
if not k:
print("y=" + str(b))
exit()
if not b:
b = ""
else:
b = "+" + str(b)
if k == 1:
k = ""
elif k == -1:
k = "-"
print(f"y={k}x{b}")
冗杂,多余。
利用列表简化输入
我们知道,同一行输入了两个数,用空格隔开,因此我们使用 split()
函数分割成单独的字符串,再利用 转化为对应的数据类型。
每一个点使用了两个临时变量,不妨改成列表。
因此我们试着写成这样:
x1, y1 = [eval(i) for i in input("A >>> ").split()]
x2, y2 = [eval(i) for i in input("B >>> ").split()]
这就利用了 for
循环和列表避免了临时变量。
合并条件判断
x, z, y = "-" if (k := (f := lambda x: int(x) if int(x) == float(x) else x)(k := (y2 - y1) / (x2 - x1))) == -1 else "" if k == 1 else k, "" if not (b := f(b := y1 - k * x1)) else b, ["", "+"][b > 0]
完整代码
(x1, y1), (x2, y2) = (f := lambda l: [eval(i) for i in input(f"{l} >>> ").split()])("A"), f("B")
x, z, y = "-" if (k := (f := lambda x: int(x) if int(x) == float(x) else x)(k := (y2 - y1) / (x2 - x1))) == -1 else "" if k == 1 else k, "" if not (b := f(b := y1 - k * x1)) else b, ["", "+"][b > 0]
print(f"y={x}x{y}{z}") if k else print(f"y={b}")