如何以Pythonic方式实现简洁的十年区间列表生成?
问题
我尝试用最少代码生成十年区间的列表,当前的实现代码如下:
def get_decade_list(start, end): nl = [] while start < end: l = list(range(start, start+10)) start += 10 nl.append(l) return nl print(get_decade_list(2001, 2201))
它的输出为:
[[2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010], [2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020], ..., [2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200]]
请问如何以Pythonic方式完成该任务?
回答
这里有几种更符合Python风格的实现方式,兼顾简洁性和可读性:
1. 列表推导式(最简洁的常规写法)
利用range的步长参数直接遍历每个十年的起始年份,用列表推导式一次性生成结果:
def get_decade_list(start, end): return [list(range(s, s + 10)) for s in range(start, end, 10)]
这个写法把原来的while循环逻辑浓缩成一行,既保留了原代码的功能,又更符合Python的惯用写法,可读性拉满。
2. 生成器版本(适合超大范围场景)
如果你的start和end差距极大(比如跨度几百年甚至更久),用生成器可以避免一次性生成所有区间列表,节省内存:
def get_decade_generator(start, end): for s in range(start, end, 10): yield list(range(s, s + 10))
使用时可以直接迭代:
for decade in get_decade_generator(2001, 2201): print(decade)
或者需要列表的话,直接转成列表即可:list(get_decade_generator(2001, 2201))。
3. 兼容非整十年结束的边界情况
如果你的end不是刚好落在十年的末尾(比如get_decade_list(2001, 2015)),上面的方法会生成到2020,但实际我们可能需要截断到end。可以用min()函数处理这种边界:
def get_decade_list(start, end): return [list(range(s, min(s + 10, end))) for s in range(start, end, 10)]
比如输入2001到2015,输出会是[[2001, ..., 2010], [2011, ..., 2015]],完美适配非整十年的结束场景。
内容的提问来源于stack exchange,提问作者user9062604

