当案例为True时如何只返回1?

时间:2014-12-31 19:05:14

标签: python boolean

我希望我的代码是' pythonic"尽可能,所以我试着尽量减少它。我希望它在输入是闰年时打印1,在不输入时打印0。

下面的代码正确打印出1和0.

a = input()
if int(1 and not a%4 and a%100 or not a%400):
    print 1
else:
    print 0

虽然这段代码打印出非常奇怪的东西。它工作正常,但不打印出来只有' 1闰年。

a = input()
print int(1 and not a%4 and a%100 or not a%400)

例如,它将打印出4为4和12为12,这是真的,但不是我想要的。有没有办法修复代码,所以只打印1个真实案例而不写更多行?

7 个答案:

答案 0 :(得分:4)

为什么重新发明轮子?此功能已通过calendar.isleap提供:

>>> import calendar
>>> calendar.isleap(2000)
True
>>> calendar.isleap(2001)
False
>>>

要将这些结果变为显式整数,只需使用int

>>> import calendar
>>> int(calendar.isleap(2000))
1
>>> int(calendar.isleap(2001))
0
>>>

答案 1 :(得分:2)

andor正在合并;他们将返回他们的一个操作数。因此,我们需要将该值转换为bool

return bool(not a%4 and a%100 or not a%400)

boolint的子集,因此我们可以直接使用它。

答案 2 :(得分:1)

代码实际上恰恰相反:

int(((not a%4 and a%100) or not a%400) != 0)

由于andor更紧密,你甚至可以删除最近的一对括号:

int((not a%4 and a%100 or not a%400) != 0)

如果是

,则一年是闰年
  

可按4而不是100400划分。

答案 3 :(得分:0)

怎么样:

def is_leap_year(year):
  return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)

print int(is_leap_year(1999))  # 0
print int(is_leap_year(2000))  # 1
print int(is_leap_year(2004))  # 1
print int(is_leap_year(2100))  # 0
print int(is_leap_year(2400))  # 1

答案 4 :(得分:0)

您可以将这样的部分最小化:

 a = input()
 print 1 if int(1 and not a % 4 and a % 100 or not a % 400) else 0

对于闰年,您的if条件并不总是评估为1,而是评估为> 0,在Python中被视为True

答案 5 :(得分:0)

编程就是沟通。无论语言如何,最好的代码都是正确,高效且易于理解的代码。复杂的布尔表达式很糟糕,应该避免。以早期退出方式编写代码更简单(并且通常更有效):

def is_leap(y):
    if y % 400 == 0:
        return True
    if y % 100 == 0:
        return False
    return y % 4 == 0

答案 6 :(得分:0)

On' Pythonic'

首先要做的事情......虽然' pythonic'这是一个有点模棱两可的术语,我认为有问题的代码不太可能被认为是' pythonic' (或者也许是用惯用的python'或者用普遍接受的python习语编写的#39;)。

单行/最小化代码通常不是pythonic'关于 - 可读性问题更重要,因此如果使代码更易于阅读和推理,则将代码分成多行是更可取的。当然,如果有内置插件或标准库函数在一行中执行某些操作,否则您必须在多行中编写,这可能是“pythonic”#。 (例如,使用calendar.isleap作为实际代码)。

要了解通常会考虑哪些值集' pythonic',请在python解释器上运行import this

将该免责声明排除在外......

分解此代码

在这种特殊情况下,在int()函数中使用w and x and y or z,然后将其作为布尔条件使用可能会不受欢迎,因为很难看出究竟发生了什么。不要在生产代码中这样做......

那么int(1 and not a%4 and a%100 or not a%400)发生了 的真正含义?

首先,链接没有括号的布尔运算符总是有点可怕,所以让我们弄清楚它是如何被评估的。根据{{​​3}},上面变为

int( (1 and (not a%4) and a%100) or (not a%400) )

您的代码采用int(A or B)形式,A进一步采用X and Y and Z形式。

现在让我们看一下docs

您发现从左到右评估每个项目,并在找到第一个False值时返回False,或者计算到最右侧的值并返回该值。

因此,1 and not a%4 and a%100True,所有三个元素必须为True或非零,然后返回的值为最右边的元素{{1} }。 所以当你跑:

a%100

>>> a = 4 >>> print int(1 and not a%4 and a%100 or not a%400) 4 4的结果。

a%100

可能的单线解决方案

如果你真的想要一个单行班,如果>>> a = 4 >>> print int(1 and not a%4 and a%100 or not a%400) # ^ ^ ^ ^ # | | | | # True True 4 False (but this isn't even evaluated because of the nature of or) 是闰年,则返回1,否则返回0,这里是:

a

print int(not a%4 and a%100 and 1 or not a%400) 放在链的最右端,这将在%100之后得到评估,因此将覆盖%100具有的任何整数值。或者:

and 1

我只是将条件强制转换为布尔值(即严格为真/假值),然后将其强制转换为严格采用1/0形式的整数。

我更喜欢这个,因为转换为布尔值并重铸为int是明确的,并且不依赖于评估顺序。但只是轻微的。最好不要做单线。

更好的解决方案

docs for boolean operations是您要在生产代码中使用的内容。

@icodez's solution如果你坚持自己写一个就应该是这样的。顺便说一句我认为这具有实际返回True / False值而不是1/0的良好属性。这绝对是更惯用的蟒蛇。