如何确定一年是否是闰年?

时间:2012-07-23 22:57:20

标签: python python-2.7

我正在尝试制作一个简单的计算器,以确定某一年是否是闰年。

根据定义,闰年可被4整除,但不能被100整除,除非它可以被400整除。

这是我的代码:

def leapyr(n):
    if n%4==0 and n%100!=0:
        if n%400==0:
            print n, " is a leap year."
    elif n%4!=0:
        print n, " is not a leap year."
print leapyr(1900)

当我在Python IDLE中尝试此操作时,模块返回None。我很确定我应该1900 is a leap year

11 个答案:

答案 0 :(得分:122)

import calendar
print calendar.isleap(1900)

Python在库模块'calendar'中已经提供了这个功能。

答案 1 :(得分:41)

作为单线功能:

def is_leap_year(year):
    """Determine whether a year is a leap year."""

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

它类似于马克的answer,但在第一次测试时短路(注意括号)。

正如P. Ortiz在评论中所注意到的那样,标准库calendar.isleap具有相同的实现,因此该函数只为您节省了导入。

答案 2 :(得分:14)

你在n上测试了三个不同的东西:

n % 4
n % 100
n % 400

1900年:

1900 % 4 == 0
1900 % 100 == 0
1900 % 400 == 300

所以1900年没有输入if条款,因为1900 % 100 != 0False

但是1900也没有输入else条款,因为1900 % 4 != 0也是False

这意味着执行到达函数的末尾并且没有看到return语句,因此返回None

此功能的重写应该有效,并且应该根据您传入的年份编号返回FalseTrue。 (请注意,与其他答案一样,您必须返回一些内容而不是打印它。)

def leapyr(n):
    if n % 400 == 0:
        return True
    if n % 100 == 0:
        return False
    if n % 4 == 0:
        return True
    else:
        return False
print leapyr(1900)

(来自Wikipedia的算法)

答案 3 :(得分:8)

整个公式可以包含在一个表达式中:

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

print n, " is a leap year" if is_leap_year(n) else " is not a leap year"

答案 4 :(得分:4)

您的函数不会返回任何内容,因此当您使用print语句将其与None语句一起使用时,这就是原因。所以要么像这样调用你的函数:

leapyr(1900)

或修改你的函数以返回一个值(使用return语句),然后由print语句打印。

注意:这并未解决您的闰年计算可能遇到的任何问题,但是对于为什么您的回答是由于您的函数调用与None一起获得print

解释

关于上述的一些简短例子:

def add2(n1, n2):
    print 'the result is:', n1 + n2  # prints but uses no *return* statement

def add2_New(n1, n2):
    return n1 + n2    # returns the result to caller

现在我打电话给他们:

print add2(10, 5)

这给出了:

the result is: 15
None

第一行来自print的内的add2()语句。当我调用的函数None时,print语句中的add2()会有一个return语句,导致None被打印。顺便说一下,如果我刚刚使用(注意, 没有 add2()语句)调用print函数:

add2()

我会在没有the result is: 15的情况下得到print语句None的输出(看起来就像你想要做的那样)。

将其与:

进行比较
print add2_New(10, 5)

给出:

15

在这种情况下,结果在函数add2_New()中计算并且没有打印语句,并返回给调用者,然后调用者依次打印它。

答案 5 :(得分:2)

除了世纪年(以00结尾的年份)之外,闰年可以被4整除。只有在完全可以被400整除的情况下,世纪年才是闰年。例如,

if( (year % 4) == 0):
    if ( (year % 100 ) == 0):

        if ( (year % 400) == 0):

            print("{0} is a leap year".format(year))
        else:

            print("{0} is not a leap year".format(year))
    else:

        print("{0} is a leap year".format(year))

else:

    print("{0} is not a leap year".format(year))

答案 6 :(得分:0)

如果您不想import calendar并申请.isleap方法,可以试试这个:

def isleapyear(year):
    if year % 4 == 0 and (year % 100 != 0 or year % 400 == 0):
        return True
    return False

答案 7 :(得分:0)

从1700年到1917年,官方日历为儒略历。从那时起,我们就使用公历系统。从儒略历到公历的转换发生在1918年,即1月31日之后的第二天是2月14日。这意味着1918年的第32天是2月14日。

在两个日历系统中,2月是唯一一个天数可变的月份,a年有29天,其他所有年份有28天。在儒略历中,leap年可被4整除,而在格里高利历中,leap年可为以下之一:

可除以400。

可以被4整除,不能被100整除。

因此leap年的程序将是:

def leap_notleap(year):

    yr = ''
    if year <= 1917:
        if year % 4 == 0:
            yr = 'leap'
        else:
            yr = 'not leap'
    elif year >= 1919:
        if (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0):
            yr = 'leap'
        else:
            yr = 'not leap'
    else:
        yr = 'none actually, since feb had only 14 days'

    return yr

答案 8 :(得分:0)

在公历中,使用三个条件来识别leap年:

  • 年份可以除以4,即is年,除非:
    • 该年份可以平均除以100,不是NOT年,除非:
      • 该年份也可以平均除以400。然后是a年。

这意味着在公历中,2000和2400年是are年,而1800、1900、2100、2200、2300和2500不是NOT年。 source

def is_leap(year):
    leap = False
    if year % 4 == 0:
        leap = True
        if year % 4 == 0 and year % 100 == 0:
            leap = False
            if year % 400 == 0:
                leap = True 
    return leap

year = int(input())
leap = is_leap(year)

if leap:
  print(f"{year} is a leap year")
else:
  print(f"{year} is not a leap year")

答案 9 :(得分:0)

“单线”中的逻辑工作正常。从个人经验来看,对我有帮助的是将语句分配给变量(以“ True”形式),然后对结果使用逻辑运算符:

A = year % 4 == 0
B = year % 100 == 0
C = year % 400 == 0

我在B语句中使用了'=='而不是“!=”,并在计算中应用了'非'逻辑运算符:

leap = A and (not B or C)

这在处理大量条件时非常方便,并且可以在编写一堆if语句之前简化布尔运算(如果适用)。

答案 10 :(得分:0)

另一种衬里:

((((y % 4) + (int((y - (y % 100)) / y) * ((y % 400) / 100))) - 1) < 0)

这是我为了好玩 (?) 而放在一起的东西,它也与 C 1:1 兼容。

(y % 4) >>>它首先通过典型的 mod-4 检查来检查年份是否为闰年。

(int((y - (y % 100)) / y) >>>然后将那些年可被 100 整除。如果年份能被 100 整除,则结果为 1,否则结果为 0。< /p>

((y % 400) / 100))) >>>接下来,年份除以 400(然后是 100,如果不是,则返回 1、2 或 3。

这两个值

(int(y - (y % 100)) / y)

&

((y % 400) / 100)))

然后相乘。如果年份不能被 100 整除,这将始终等于 0,否则如果它可以被 100 整除,但不能被 400 整除,则结果为 1、2 或 3。如果它可以被 100 和 400 整除,则将导致 0。

这个值被加到 (y % 4) 中,如果年份是闰年,在考虑了边缘情况后,它只会等于 0。

最后,从这个剩余值中减去 1,如果年份是闰年,则结果为 -1,如果不是,则为 0、1 或 2。使用小于运算符将此值与 0 进行比较。如果年份是闰年,这将导致 True(或 1,如果在 C 中使用),否则将返回 False(或 0,如果在 C 中使用)。

请注意:此代码效率极低,令人难以置信的不可读,并且不利于任何尝试遵循正确做法的代码。这是我的一个练习,看看我是否可以这样做,仅此而已。

此外,请注意 ZeroDivisionErrors 是输入年份等于 0 的结果,必须加以考虑。

例如,对 1000 次执行的非常基本的 timeit 比较表明,与使用简单 if 语句和模运算符的等效代码块相比,此单行代码比其 if 块等效代码慢了大约 5 倍。< /p>

话虽如此,我确实觉得它非常有趣!