Python基础:复数类型complex应用场景详解 Python基础复数类型complex应用场景详解一、开篇Python内置复数——一个被低估的特性如果你不是数学或物理专业的可能从高中毕业后就没再接触过复数。你可能会想“我写程序永远用不到复数吧”不一定。复数在信号处理、图像处理、电子电路仿真、量子计算、3D图形学等领域都有实际应用。而Python是为数不多的内置复数类型的主流编程语言——在很多语言中你需要引入第三方库才能处理复数。⌨️ 这篇文章有两个目的一是让你了解Python中的复数怎么用二是让你知道它在什么场景下有用。即使你平时用不到了解Python有这个内置能力也是一件好事。二、复数的数学基础回顾2.1 5分钟复习复数复数由两部分组成实部real part和虚部imaginary part。形如a bj 在数学中通常写作 a biPython中用 j 代替 i其中a是实部一个实数b是虚部系数一个实数j是虚数单位满足 j² -1# Python中的复数z134j# 实部3, 虚部4z21-2j# 实部1, 虚部-2z35j# 纯虚数实部0注意不能写成 j5z420j# 其实就是实数2但类型是complex⚠️ 注意Python中使用j而不是数学中的i来表示虚数单位。这是工程领域的惯例因为i常被用作电流的符号。三、Python中复数的创建3.1 字面量方式# 基本创建a34jb-1-2jc5j# 等于 0 5jd2-0j# 等于 2 0j# 注意虚部系数必须紧挨着j# e 1 j # NameErrorj被当作变量名e11j# OK3.2 使用complex()函数# 从一个参数z1complex(5)# (50j)z2complex(3.14)# (3.140j)# 从两个参数实部, 虚部z3complex(3,4)# (34j)z4complex(-1,2.5)# (-12.5j)# 从字符串不能有空格z5complex(34j)# (34j)z6complex(-1-2j)# (-1-2j)z7complex(5j)# 5jz8complex(3)# (30j)# 这些会报错# complex(3 4j) # 字符串中有空格# complex(34i) # Python用j不是i3.3 获取实部和虚部z34jprint(z.real)# 3.0注意返回float类型print(z.imag)# 4.0# 复数的共轭虚部取反print(z.conjugate())# (3-4j)四、复数的运算4.1 基本算术运算a34jb1-2j# 加法(34j) (1-2j) 42jprint(ab)# (42j)# 减法(34j) - (1-2j) 26jprint(a-b)# (26j)# 乘法(34j)(1-2j) 3-6j4j-8j² 3-2j8 11-2jprint(a*b)# (11-2j)# 除法(34j)/(1-2j)print(a/b)# (-12j)# 幂运算print(a**2)# (-724j) — 因为 (34j)² 924j16j² 924j-16 -724j4.2 比较运算a34jb34j# 可以比较相等print(ab)# Trueprint(a!b)# False# 不能比较大小# print(a b) # TypeError: not supported between complex numbers# print(a b) # 同上⚠️ 复数不能比较大小——这在数学上就没有意义。复数之间只能判断相等或不等。4.3 内置函数对复数的支持importmathimportcmath# 复数的数学函数z34j# abs()复数的模magnitude# |34j| sqrt(3² 4²) sqrt(25) 5print(abs(z))# 5.0# pow()幂运算print(pow(z,2))# (-724j)# round()不能用于复数# round(z) # TypeError# cmath模块复数的数学函数print(cmath.sqrt(z))# (21j)因为(2j)² 44jj² 34j# 复数的极坐标表示print(cmath.polar(z))# (5.0, 0.9272952180016122)# 返回 (模, 辐角) (5.0, arctan(4/3))# 从极坐标恢复复数modulus,angle5.0,0.9272952180016122print(cmath.rect(modulus,angle))# (34j)# 欧拉公式e^(jx) cos(x) j*sin(x)x0.5print(cmath.exp(1j*x))# (0.877580.47943j)print(complex(cmath.cos(x),cmath.sin(x)))# 手动计算验证4.4 cmath模块常用函数importcmath z11j# 指数和对数print(cmath.exp(z))# e^zprint(cmath.log(z))# ln(z)print(cmath.log10(z))# log10(z)# 三角函数print(cmath.sin(z))print(cmath.cos(z))print(cmath.tan(z))# 反三角函数print(cmath.asin(z))print(cmath.acos(z))print(cmath.atan(z))# 双曲函数print(cmath.sinh(z))print(cmath.cosh(z))print(cmath.tanh(z))# 判断函数print(cmath.isinf(complex(float(inf),0)))# Trueprint(cmath.isnan(complex(float(nan),0)))# Trueprint(cmath.isclose(12j,12.0000000001j))# True五、复数的实际应用场景5.1 信号处理傅里叶变换importcmathdefdiscrete_fourier_transform(samples): 离散傅里叶变换DFT 输入时域信号采样点列表实数 输出频域复数列表 nlen(samples)result[]forkinrange(n):# 计算第k个频率分量frequency_component0jfortinrange(n):angle-2*cmath.pi*1j*k*t/n frequency_componentsamples[t]*cmath.exp(angle)result.append(frequency_component)returnresult# 示例分析一个包含两个频率成分的信号importmath# 生成采样信号50Hz 120Hz的正弦波sample_rate500# 采样率duration1.0# 1秒n_samplesint(sample_rate*duration)samples[]foriinrange(n_samples):ti/sample_rate valuemath.sin(2*math.pi*50*t)0.5*math.sin(2*math.pi*120*t)samples.append(value)# 执行DFTfrequency_spectrumdiscrete_fourier_transform(samples)# 显示前10个频率分量的幅度print(频率分析结果)foriinrange(10):magnitudeabs(frequency_spectrum[i])frequencyi*sample_rate/n_samplesprint(f{frequency:.0f}Hz: 幅度{magnitude:.2f})5.2 图像处理复数表示像素值# 在图像处理中可以使用复数来表示二维坐标系中的点# 复数的实部表示x坐标虚部表示y坐标defrotate_point(x,y,angle_degrees):用复数实现二维平面上的点旋转# 创建表示点的复数pointcomplex(x,y)# 创建旋转因子e^(jθ) cos(θ) j*sin(θ)importmath angle_radiansmath.radians(angle_degrees)rotationcomplex(math.cos(angle_radians),math.sin(angle_radians))# 旋转复数乘法rotatedpoint*rotationreturnrotated.real,rotated.imag# 测试将点(1, 0)旋转90度x,yrotate_point(1,0,90)print(f(1, 0)旋转90度后({x:.2f},{y:.2f}))# (0.00, 1.00)# 放大/缩小defscale_point(x,y,factor):缩放点pointcomplex(x,y)scaledpoint*factorreturnscaled.real,scaled.imag x,yscale_point(3,4,2)print(f(3, 4)放大2倍({x},{y}))# (6.0, 8.0)5.3 电路分析阻抗计算# 在交流电路分析中阻抗电阻电抗用复数表示# Z R jX# R电阻实部X电抗虚部# 电感X_L jωL电容X_C 1/(jωC) -j/(ωC)defimpedance_resistor(r):纯电阻阻抗returncomplex(r,0)defimpedance_inductor(inductance,frequency):电感阻抗Z_L jωLomega2*3.14159*frequencyreturncomplex(0,omega*inductance)defimpedance_capacitor(capacitance,frequency):电容阻抗Z_C 1/(jωC)omega2*3.14159*frequencyreturncomplex(0,-1/(omega*capacitance))defparallel_impedance(z1,z2):并联阻抗return(z1*z2)/(z1z2)defseries_impedance(*impedances):串联阻抗returnsum(impedances)# 示例RLC串联电路R100.0# 100欧姆电阻L0.1# 100毫亨电感C10e-6# 10微法电容f1000.0# 1000Hz频率Z_Rimpedance_resistor(R)Z_Limpedance_inductor(L,f)Z_Cimpedance_capacitor(C,f)Z_totalseries_impedance(Z_R,Z_L,Z_C)print(f总阻抗{Z_total})print(f阻抗模{abs(Z_total):.2f}欧姆)print(f相位角{cmath.phase(Z_total):.2f}弧度)5.4 分形生成曼德勃罗集defmandelbrot(c,max_iterations100): 判断一个复数c是否属于曼德勃罗集 返回迭代次数用于着色如果在max_iterations内不发散则返回max_iterations z0jforninrange(max_iterations):zz*zcifabs(z)2:returnnreturnmax_iterationsdefgenerate_mandelbrot(width80,height40,max_iter50):生成曼德勃罗集的ASCII艺术x_min,x_max-2.0,1.0y_min,y_max-1.0,1.0foryinrange(height):lineforxinrange(width):# 将像素坐标映射到复数平面realx_min(x/width)*(x_max-x_min)imagy_min(y/height)*(y_max-y_min)ccomplex(real,imag)# 计算这个点属于曼德勃罗集的程度mmandelbrot(c,max_iter)# 用不同字符表示不同深度ifmmax_iter:line#elifmmax_iter*0.8:line*elifmmax_iter*0.5:lineelifmmax_iter*0.2:line.else:line print(line)# 生成曼德勃罗集终端中的ASCII艺术generate_mandelbrot(100,40)六、复数的类型转换# 复数 → 其他类型z34j# 复数 → 字符串print(str(z))# (34j)# 复数 → 整数/浮点数不行# int(z) # TypeError# float(z) # TypeError# 但可以取模magnitudeabs(z)# 5.0float类型# 其他类型 → 复数print(complex(5))# (50j)print(complex(3.14))# (3.140j)print(complex(3,4))# (34j)print(complex(12j))# (12j)七、使用复数的注意事项7.1 虚部符号问题importcmath# 对负数开方# math.sqrt(-1) # ValueErrorresultcmath.sqrt(-1)# 1jprint(result)# 但cmath.sqrt返回复数print(cmath.sqrt(4))# (20j)——即使结果是实数也返回complex类型print(cmath.sqrt(-4))# 2j——令人困惑的写法实际是02j# 如果你想要实数需要检查defsafe_sqrt(x):安全开方正数返回float负数返回complexifx0:importmathreturnmath.sqrt(x)else:returncmath.sqrt(x)print(safe_sqrt(4))# 2.0print(safe_sqrt(-4))# 2j7.2 复数的实部和虚部都是floatz34jprint(type(z.real))# class floatprint(type(z.imag))# class float# 这意味着实部或虚部也可以是float中的特殊值z1complex(float(inf),0)# (inf0j)z2complex(0,float(nan))# (nanj)print(z1,z2)八、本篇小节✅ Python内置复数类型——一个你可能不常用到但在需要时非常方便的特性创建方式字面量34j或complex(3, 4)或complex(34j)基本运算加减乘除、幂运算都支持但不能比较大小cmath模块提供复数的sin、cos、exp、log、sqrt等函数实际应用信号处理傅里叶变换、图像旋转、电路分析、分形生成注意点虚部系数必须紧挨j4j而不是4 j、Python用j不是i 复数是Python内置电池理念的又一个体现。你可能90%的日常开发中用不到它但当你的项目涉及信号处理、科学计算或图形学的时候Python不用你额外装任何库就能搞定复数运算。下一篇我们来学习布尔类型bool。