整活:记一次 Python 压行的经历。


为什么我要写这篇文章?

  1. 众所周知,C++ 的所有非预处理可以压到一行,因为人家有分号。但是 Python 靠缩进!
  2. 本来想写一个一次函数计算器的,但是为了方便想压行。
  3. 前不久,我了解到 Python 海象运算符。起初觉得这和 C++ 的特性一样嘛,经常会在记忆化搜索等类似的算法中用到。然后在实战中应用了一下,就突然发掘出了 Python 压行的玩法。

警告:
压行是为了整活,有时可以帮助减少代码体积。但是这样做很可能降低代码可读性,而且极难调试!
尽量不要在开发使用这样的手段!


需求和推论

需求:平面直角坐标系内,给出两个不同的点 A(x1,y1)A(x_1,y_1)B(x2,y2)B(x_2,y_2),求直线 ABAB 的表达式。
方法:待定系数法。
yAB=kx+by_{AB}=kx+b.
A(x1,y1)A(x_1,y_1)B(x2,y2)B(x_2,y_2) 代入,得 {y1=kx1+by2=kx2+b\left\{\begin{matrix}y_1=kx_1+b\\y_2=kx_2+b\end{matrix}\right..
所以 {k=y2y1x2x1b=y1kx1\left\{\begin{matrix}k=\frac{y_2-y_1}{x_2-x_1}\\b=y_1-kx_1\end{matrix}\right..

其他要求:

  1. 结果应该化成 y=kx+by=kx+b 的形式。
  2. 输入共两行,每行两个数,用空格隔开,分别表示 AABB 两点的横、纵坐标。输入可能为小数。
  3. k=±1k=\pm1 时,化为 y=±x+by=\pm x+b 的形式。
  4. b=0b=0 时,化为 y=kxy=kx 的形式。
  5. k=0k=0 时,化为 y=by=b 的形式。
  6. 能化为整数的化为整数,不要有 1.01.02.02.0 等的数出现。

原始代码

_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() 函数分割成单独的字符串,再利用 evaleval 转化为对应的数据类型。
每一个点使用了两个临时变量,不妨改成列表。
因此我们试着写成这样:

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}")