我已经阅读并理解了浮点舍入问题,例如:
>>> sum([0.1] * 10) == 1.0
False
>>> 1.1 + 2.2 == 3.3
False
>>> sin(radians(45)) == sqrt(2) / 2
False
我还知道如何使用math.isclose()和cmath.isclose()解决这些问题。
问题是如何将这些工作方法应用于Python的匹配/case语句。我希望这样做:
match 1.1 + 2.2:
case 3.3:
print('hit!') # currently, this doesn't match
雷蒙德的答案非常花哨和符合人体工程学,但对于可能更简单的事情来说,似乎有很多魔法。更简单的版本只是捕获计算值,并明确检查事物是否“接近”,例如:
import math
match 1.1 + 2.2:
case x if math.isclose(x, 3.3):
print(f"{x} is close to 3.3")
case x:
print(f"{x} wasn't close)
我还建议只使用cmath。isclose()在实际需要的位置/时间,使用适当的类型可以确保代码按预期执行。
解决方案的关键是构建一个覆盖__eq__
方法并用近似匹配替换它的包装器:
import cmath
class Approximately(complex):
def __new__(cls, x, /, **kwargs):
result = complex.__new__(cls, x)
result.kwargs = kwargs
return result
def __eq__(self, other):
return cmath.isclose(self, other, **self.kwargs)
它为浮点值和复数值创建近似相等测试:
>>> Approximately(1.1 + 2.2) == 3.3
True
>>> Approximately(1.1 + 2.2, abs_tol=0.2) == 3.4
True
>>> Approximately(1.1j + 2.2j) == 0.0 + 3.3j
True
以下是如何在匹配/case语句中使用它:
for x in [sum([0.1] * 10), 1.1 + 2.2, sin(radians(45))]:
match Approximately(x):
case 1.0:
print(x, 'sums to about 1.0')
case 3.3:
print(x, 'sums to about 3.3')
case 0.7071067811865475:
print(x, 'is close to sqrt(2) / 2')
case _:
print('Mismatch')
这将输出:
0.9999999999999999 sums to about 1.0
3.3000000000000003 sums to about 3.3
0.7071067811865475 is close to sqrt(2) / 2
我正在计算非负p的Lp距离函数。除了p=0和p=∞ 内置的pow()函数可以很好地发挥作用。在学习结构模式匹配之前,我使用了字典和异常处理: 有些人不希望这里有例外。因此,我将该片段改写为以下内容: 为什么大小写inf不正确(Python v3.10.2)?
我无法运行此代码: 我在Python中找不到匹配关键字。 我在这里找到的:https://www.python.org/dev/peps/pep-0622/#the-match语句 有什么想法吗?
我有一个字符串,我正试图根据几个regex模式验证它,我希望由于模式匹配在3.10中可用,我可以使用它来代替创建if-else块。 考虑一个字符串'validateString',其可能的值1021102,1.25.32string021。 我尝试的代码如下所示。 对于正则表达式1、2和3,我尝试了字符串正则表达式模式,还重新设置了。编译对象,但它似乎不起作用。 我一直试图在互联网上找到这方面的例
我一直在玩Python 3.10中的结构模式匹配,但不知道如何让它匹配一组。例如,我尝试过: 我尝试过: 以及: 我想有一种方法可以做到这一点,因为我们可以匹配其他对象,我只是缺少正确的语法,但我想不出还有什么其他方法可以尝试。任何帮助都将不胜感激!谢谢
字面量 变量 占位符