打印出您从该额外步骤中获得的信息可能会有所帮助:
>>> months_abbvs
{'apr': 'April',
'aug': 'August',
'dec': 'December',
'feb': 'February',
'jan': 'January',
'jul': 'July',
'jun': 'June',
'mar': 'March',
'may': 'May',
'nov': 'November',
'oct': 'October',
'sep': 'September'}
因此,您有一个小写缩写到完整月份名称的映射。
这是如何运作的?好吧,首先,让我们看一下表达式的作用:
>>> m = 'December'
>>> m[:3].lower()
'dec'
>>> m[:3].lower(), m
('dec', 'December')
所以,理解只是每个月都这样做:
>>> [(m[:3].lower(), m) for m in months]
[('jan', 'January'),
('feb', 'February'),
('mar', 'March'),
('apr', 'April'),
('may', 'May'),
('jun', 'June'),
('jul', 'July'),
('aug', 'August'),
('sep', 'September'),
('oct', 'October'),
('nov', 'November'),
('dec', 'December')]
正如本教程中更详细地解释的那样,推导式基本上是循环的简写。特别是,这:
>>> m2 = [<expression with m> for m in months]
… 相当于:
>>> m2 = []
>>> for m in months:
... m2.append(<expression with m>)
使用生成器表达式而不是列表推导式仅意味着将序列构建为惰性迭代器而不是列表。
然后将结果(无论哪种方式)传递给dict
构建一个字典,将每个元组的第一个值映射到第二个值。
你可以把这一切写得更易读,作为字典理解:
months_abbvs = {m[:3].lower(): m for m in months}
更好的是m[:3].lower()
,与其重复编写,不如给它起一个好听的名字并使用它:
def abbreviate(m):
return m[:3].lower()
months_abbvs = {abbreviate(m): m for m in months}
接着:
def valid_month(month):
if month:
short_month = abbreviate(month)
return month_abbvs.get(short_month)
现在,您在新版本中输入的内容是:
short_month = month[:3].lower()
return month_abbvs.get(short_month)
因为month_abbvs
is a dict
(你可以通过打印出来,或者仅仅从它是通过调用dict
某些东西创建的事实来判断),get
方法是dict.get
. 因此,如链接文档中所述,month_abbvs.get(short_month)
与 相同months_abbvs[short_month]
,只是如果short_month
找不到密钥,您将得到None
,而不是引发异常。
因此,如果给定'October'
,您将设置short_month
为'oct'
。然后你在缩写字典中查找它,它返回'October'
. 如果给定'OCT'
or'october'
或'octal digit string'
,你也会返回同样的东西。由于任何非空字符串都是真实的,如果你做了类似的事情if valid_month('October'):
,那将是真实的。
但是,如果给定,比如说,,'Muhammed'
你将设置short_month
为'muh'
。然后你查了一下,它不存在。如上所述,该get
方法返回None
未知键,因此您将返回None
. 既然None
是假的,如果你做过类似的事情if valid_month('Muhammed'):
,那就不是真的。
换句话说,它使函数更宽松——这可能是一种改进,也可能是一件坏事(或者可能两者兼而有之——也许你想'OCT'
工作,但不是'octal digit string'
)。