一个复数可以在 python 中解包成 x 和 y 吗?

Can a complex number be unpacked into x and y in python?

我希望能够像这样将复数解包为其实部和虚部:

>>> z = 3 + 5j
>>> x, y = z
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot unpack non-iterable complex object

但是我得到一个错误。我当然可以:

>>> x, y = z.real, z.imag

但这看起来重复而且可读性不强,我可以通过编写这样的函数来改进它:

def unpack(z: complex) -> tuple[float, float]:
    return z.real, z.imag
x, y = unpack(z)

但我觉得应该有更好的方法。

您知道将复数分解为实部和虚部的更好方法吗?

你可以做的一件事是 subclass complex 并实现自定义 __iter__ 方法,returns 你寻找的解压版本。

在这种情况下我选择称它为 complez,因为 z 通常是复数的符号。

import cmath

class complez(complex):
    def __iter__(self):
        return iter((self.real, self.imag))

z = complez(3, 5)
x, y = z
print(x, y)
# 3.0 5.0

如果您不介意覆盖现有 complex,您也可以执行以下操作。使用这种方法,您可以在整个代码中继续使用 complex class,而无需对命名进行任何更改。

import builtins
import cmath

class complex(builtins.complex):
    def __iter__(self):
        return iter((self.real, self.imag))

z = complex(3, 5)
x, y = z
print(x, y)
# 3.0 5.0

(从技术上讲,您也可以放弃使用 builtins 模块)。

在任何一种情况下,标准的解包运算符也可以工作,例如

print(*z)
# 3.0 5.0

注意: 这解决了您眼前的问题,但确实会产生后果。当您对这些新数字执行操作时,例如添加 2 complez 个数字,你会得到一个 complex 个数字结果——它没有方便的 __iter__ 定义,所以你必须覆盖其他方法来解释这一边-影响。例如:

def __add__(self, other):
    return complez(super().__add__(other))

因此,这种方法确实会在生成完全通用的解决方案时产生更多的开销。但是,这是为了方便自然拆包而做出的权衡。