我希望我的代码是' 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个真实案例而不写更多行?
答案 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)
and
和or
正在合并;他们将返回他们的一个操作数。因此,我们需要将该值转换为bool
:
return bool(not a%4 and a%100 or not a%400)
bool
是int
的子集,因此我们可以直接使用它。
答案 2 :(得分:1)
代码实际上恰恰相反:
int(((not a%4 and a%100) or not a%400) != 0)
由于and
比or
更紧密,你甚至可以删除最近的一对括号:
int((not a%4 and a%100 or not a%400) != 0)
如果是
,则一年是闰年可按
4
而不是100
,或按400
划分。
答案 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)
首先要做的事情......虽然' 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%100
为True
,所有三个元素必须为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的良好属性。这绝对是更惯用的蟒蛇。