60

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

根据定义,闰年可以被四整除,但不能被一百整除,除非它可以被四百整除。

这是我的代码:

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.

4

12 回答 12

184

使用calendar.isleap

import calendar
print(calendar.isleap(1900))
于 2012-07-24T00:40:47.063 回答
60

作为一个单行函数:

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)

它类似于Mark's answer,但在第一次测试时短路(注意括号)。

calendar.isleap或者,您可以使用具有完全相同实现的标准库:

from calendar import isleap
print(isleap(1900))  # False
于 2015-06-08T16:10:51.847 回答
19

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

n % 4
n % 100
n % 400

对于 1900:

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

所以 1900 没有进入if子句,因为1900 % 100 != 0isFalse

但是 1900 也没有进入else子句,因为1900 % 4 != 0is alsoFalse

这意味着执行到了函数的末尾并且没有看到 return 语句,所以它返回None.

您的函数的这种重写应该有效,并且应该返回FalseTrue根据您传递给它的年份编号。(请注意,与其他答案一样,您必须返回一些东西而不是打印它。)

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

(来自维基百科的算法)

于 2012-07-23T23:05:32.740 回答
11

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

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"
于 2012-07-24T00:31:51.220 回答
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()Noneadd2()Noneadd2() print

add2()

the result is: 15如果没有None(看起来像您正在尝试做的事情),我只会得到 print 语句的输出。

将此与以下内容进行比较:

print add2_New(10, 5)

这使:

15

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

于 2012-07-23T23:01:28.327 回答
2

闰年可以被 4 整除,但世纪年(以 00 结尾的年份)除外。只有当世纪年能被 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))
于 2017-02-16T12:03:14.940 回答
0

如果你不想import calendar应用.isleap方法,你可以试试这个:

def isleapyear(year):
    if year % 4 == 0 and (year % 100 != 0 or year % 400 == 0):
        return True
    return False
于 2018-02-12T12:58:54.470 回答
0

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

  • 年份可以被4整除,是闰年,除非:
    • 年份可以除以 100,它不是闰年,除非:
      • 年份也能被 400 整除。那么就是闰年。

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

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")
于 2020-09-12T16:48:20.547 回答
0

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

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

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

leap = A and (not B or C)

这对一组更大的条件很有用,并在编写一大堆 if 语句之前在适用的情况下简化布尔运算。

于 2020-09-24T04:59:52.587 回答
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。

((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 倍。

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

于 2021-02-05T19:03:02.727 回答
0

缺少的部分是使用 return 语句:

def is_year_leap(year):
    if year % 100 == 0:
        if year %  400 == 0:
            return True
        else:
            return False

    elif year % 4 == 0:
        return True

    else:
        return False

x = is_year_leap(int(input('Enter any year: ')))
print(x)
于 2021-10-31T18:43:34.450 回答
-1

从 1700 年到 1917 年,官方日历是儒略历。从那以后他们我们使用公历系统。从儒略历到公历的过渡发生在 1918 年,当时 1 月 31 日之后的第二天是 2 月 14 日。这意味着 1918 年的第 32 天,是 2 月 14 日。

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

能被 400 整除。

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

所以闰年的程序是:

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
于 2019-11-29T04:24:43.847 回答