是否有更紧凑或pythonic的方式来编写布尔表达式
a + b == c or a + c == b or b + c == a
Run Code Online (Sandbox Code Playgroud)
我想出来了
a + b + c in (2*a, 2*b, 2*c)
Run Code Online (Sandbox Code Playgroud)
但这有点奇怪.
Bar*_*rry 204
如果我们看一下Python的禅,重点是我的:
Tim Peters的Python之禅
美丽胜过丑陋.
显式优于隐式.
简单比复杂更好.
复杂比复杂更好.
Flat优于嵌套.
稀疏优于密集.
可读性很重要.
特殊情况不足以打破规则.
虽然实用性胜过纯洁.
错误不应该默默地传递.
除非明确沉默.
面对模棱两可,拒绝猜测的诱惑.
应该有一个 - 最好只有一个 - 明显的方法来做到这一点.
虽然这种方式起初可能并不明显,除非你是荷兰人.
现在比永远好.
虽然从来没有经常好过正确的现在.
如果实施很难解释,这是一个坏主意.
如果实现很容易解释,那可能是个好主意.
命名空间是一个很棒的主意 - 让我们做更多的事情吧!
最Pythonic解决方案是最清晰,最简单,最容易解释的解决方案:
a + b == c or a + c == b or b + c == a
Run Code Online (Sandbox Code Playgroud)
更好的是,你甚至不需要知道Python来理解这段代码!就这么简单.这是毫无保留的最佳解决方案.其他任何东西都是智力手淫.
此外,这也可能是性能最佳的解决方案,因为它是所有短路提案中唯一的解决方案.如果a + b == c,只进行一次添加和比较.
Ale*_*rga 101
解决a的三个等式:
a in (b+c, b-c, c-b)
Run Code Online (Sandbox Code Playgroud)
Mar*_*som 54
Python有一个any函数可以or对序列的所有元素进行处理.在这里,我已将您的语句转换为3元素元组.
any((a + b == c, a + c == b, b + c == a))
Run Code Online (Sandbox Code Playgroud)
请注意,这or是短路的,因此如果计算单个条件很昂贵,那么保留原始构造可能会更好.
Cyp*_*ase 40
如果你知道你只处理正数,这将是有效的,并且非常干净:
a, b, c = sorted((a, b, c))
if a + b == c:
do_stuff()
Run Code Online (Sandbox Code Playgroud)
正如我所说,这只适用于正数; 但是如果你知道它们会变得积极,那么IMO就是一个非常易读的解决方案,甚至直接在代码中而不是函数中.
你可以这样做,这可能会做一些重复的计算; 但是您没有将性能指定为您的目标:
from itertools import permutations
if any(x + y == z for x, y, z in permutations((a, b, c), 3)):
do_stuff()
Run Code Online (Sandbox Code Playgroud)
或者没有permutations()和重复计算的可能性:
if any(x + y == z for x, y, z in [(a, b, c), (a, c, b), (b, c, a)]:
do_stuff()
Run Code Online (Sandbox Code Playgroud)
我可能会把这个或任何其他解决方案放入一个函数中.然后你可以干净地调用代码中的函数.
就个人而言,除非我需要更多的代码灵活性,否则我会在你的问题中使用第一种方法.它简单而有效.我仍然可以把它放到一个函数中:
def two_add_to_third(a, b, c):
return a + b == c or a + c == b or b + c == a
if two_add_to_third(a, b, c):
do_stuff()
Run Code Online (Sandbox Code Playgroud)
这是非常好的Pythonic,它很可能是最有效的方法(额外的函数调用); 虽然你不应该过多担心性能,除非它实际上引起了一个问题.
Tha*_*ell 17
如果您只使用三个变量,那么您的初始方法:
a + b == c or a + c == b or b + c == a
Run Code Online (Sandbox Code Playgroud)
已经非常pythonic.
如果您计划使用更多变量,那么您的推理方法包括:
a + b + c in (2*a, 2*b, 2*c)
Run Code Online (Sandbox Code Playgroud)
很聪明,但我们想想为什么.为什么这样做?
通过一些简单的算法,我们看到:
a + b = c
c = c
a + b + c == c + c == 2*c
a + b + c == 2*c
Run Code Online (Sandbox Code Playgroud)
而这将是成立的,无论对于A,B或C,这意味着是的,它会等于2*a,2*b或2*c.对于任何数量的变量都是如此.
因此,快速编写此代码的一种好方法是简单地列出变量列表,并根据doubled值列表检查它们的总和.
values = [a,b,c,d,e,...]
any(sum(values) in [2*x for x in values])
Run Code Online (Sandbox Code Playgroud)
这样,要在方程式中添加更多变量,您只需要通过'n'个新变量编辑值列表,而不是写'n'方程式
Arc*_*num 12
以下代码可用于迭代地比较每个元素与其他元素的总和,这是从整个列表的总和计算的,不包括该元素.
l = [a,b,c]
any(sum(l)-e == e for e in l)
Run Code Online (Sandbox Code Playgroud)
Jac*_*ack 10
不要试图简化它.相反,用函数命名你正在做的事情:
def any_two_sum_to_third(a, b, c):
return a + b == c or a + c == b or b + c == a
if any_two_sum_to_third(foo, bar, baz):
...
Run Code Online (Sandbox Code Playgroud)
用"聪明"替换条件可能会使其更短,但不会使其更具可读性.然而,离开它的方式也不是很易读,因为知道你为什么一眼就检查这三个条件是很棘手的.这使得您正在检查的内容非常清晰.
关于性能,这种方法确实增加了函数调用的开销,但从不牺牲性能的可读性,除非你找到了一个绝对必须修复的瓶颈.并且总是测量,因为一些聪明的实现能够在某些情况下优化并内联一些函数调用.
Python 3:
(a+b+c)/2 in (a,b,c)
(a+b+c+d)/2 in (a,b,c,d)
...
Run Code Online (Sandbox Code Playgroud)
它可以扩展到任意数量的变量:
arr = [a,b,c,d,...]
sum(arr)/2 in arr
Run Code Online (Sandbox Code Playgroud)
但是,一般来说我同意除非你有三个以上的变量,否则原始版本更具可读性.
(a+b-c)*(a+c-b)*(b+c-a) == 0
Run Code Online (Sandbox Code Playgroud)
如果任意两个项的总和等于第三项,那么其中一个因子将为零,使整个产品为零.
怎么样:
a == b + c or abs(a) == abs(b - c)
Run Code Online (Sandbox Code Playgroud)
请注意,如果变量是无符号的,这将不起作用.
从代码优化的角度来看(至少在x86平台上),这似乎是最有效的解决方案.
现代编译器将通过使用巧妙的CDQ,XOR和SUB指令序列来内联abs()函数调用并避免符号测试和后续条件分支.因此,上述高级代码仅用低延迟,高吞吐量ALU指令和仅两个条件表示.
| 归档时间: |
|
| 查看次数: |
13424 次 |
| 最近记录: |