You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python生成曼德博集合的单行晦涩代码工作原理解析

曼德博集合Python单行代码原理解析

这段晦涩单行代码的核心是用匿名lambda实现了曼德博集合的核心迭代逻辑,绕的写法主要是为了在不使用def定义命名函数的前提下实现递归。

1. 各变量的定义与来源

所有变量的绑定逻辑顺着调用链拆解如下:

  • a:最外层第一个lambda的形参,这个lambda被调用时,传入的实参是后面实现迭代逻辑的递归核心lambda,作用是把递归函数自身传入内部,解决lambda无法直接自引用递归的问题,是极简Y不动点组合子的实现部分。
  • s:递归核心lambda的第一个形参,接收的实参就是递归函数自身(和外层的a指向完全相同的函数对象),用来在迭代逻辑内部触发下一轮递归调用。
  • z:曼德博迭代过程中的当前复数值,初始调用时传入固定值0,每一轮递归都会更新为z*z + c,当递归终止时返回最终的z值,用来计算模长判断点是否属于曼德博集合。
  • c:复平面上待判定点的复数坐标,短测试代码里取值为0.02*x + 0.05j*y,长代码里是遍历x、y坐标范围映射到复平面的每个采样点,整个迭代过程中c的值固定不变。
  • n:剩余迭代次数,短测试代码初始传入10、长代码初始传入40,每完成一轮递归n就减1,当n等于0时停止迭代,返回当前的z值。
  • 补充:代码里的x、y是复平面坐标的映射参数,短测试代码里是提前赋值的固定值,长代码里是双层循环遍历的行列索引,用来把字符画的行列位置映射到复平面的对应坐标。

2. 改写为常规函数的实现与调用

原来的嵌套lambda写法纯粹是为了压缩成单行、用匿名函数实现递归,换成常规def定义函数的写法逻辑会非常清晰,不需要绕高阶函数传自身的逻辑:

核心迭代函数定义

def mandel_iter(z, c, n):
    # 迭代次数耗尽,返回最终z值
    if n == 0:
        return z
    # 按曼德博公式更新z,剩余迭代次数减1,继续递归
    return mandel_iter(z * z + c, c, n - 1)

短测试代码对应调用

x = 10
y = 5
# 初始z=0,传入对应c值,迭代10次后取模长
res = abs(mandel_iter(0, 0.02*x + 0.05j*y, 10))
print(res)

完整分形字符画实现

对应原来的长代码,改写后逻辑和输出完全一致:

def mandel_iter(z, c, n):
    if n == 0:
        return z
    return mandel_iter(z * z + c, c, n - 1)

canvas = []
# 遍历字符画的行(对应复平面虚轴)
for y in range(-20, 20):
    line = []
    # 遍历字符画的列(对应复平实轴)
    for x in range(-80, 20):
        c = 0.02 * x + 0.05j * y
        z_final = mandel_iter(0, c, 40)
        # 迭代后模长小于2判定为集合内点,输出*,否则输出空格
        line.append('*' if abs(z_final) < 2 else ' ')
    canvas.append(''.join(line))

print('\n'.join(canvas))

注:曼德博集合的判定规则为:从z=0开始迭代z = z² + c,若经过足够多次迭代后z的模长始终小于2,则点c属于曼德博集合,这段代码就是完全按照这个规则实现的。

内容的提问来源于stack exchange,提问作者Ivar Wine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:39:23