如何使用Python map为每个输入生成多值并得到扁平化列表
问题:如何用map实现Event列表的扁平化展开?
给定如下数据结构:
class Event: start: datetime end: datetime
现有一个list[Event],需要生成一个扁平化的list[datetime],每个原始Event对应其start和end两个时间条目。示例如下:
event_a = Event(start=datetime(2024,6,14), end=datetime(2024,6,15)) event_b = Event(start=datetime(2024,7,14), end=datetime(2024,7,15)) input_list = [event_a, event_b] def construct(input_list: list[Event]) -> list[datetime]: ... output_list = construct(input_list) # 预期输出: # [datetime(2024,6,14), datetime(2024,6,15), datetime(2024,7,14), datetime(2024,7,15)]
已知可以用列表推导式实现,但希望用map高效完成。尝试了以下代码:
output_list = map(lambda x: (x.start, x.end), input_list)
得到的结果是嵌套元组的迭代器:
[(datetime(2024,6,14), datetime(2024,6,15)), (datetime(2024,7,14), datetime(2024,7,15))]
想知道是否可以调整map的lambda表达式,直接返回扁平化的列表?
解决方案
单独只用map无法直接生成扁平化列表,因为map的每个元素只能返回单个值(包括元组这类容器)。要实现扁平化,需要额外步骤展开map返回的迭代器,以下是两种可行方案:
方法1:结合itertools.chain.from_iterable展开
from itertools import chain from datetime import datetime class Event: def __init__(self, start: datetime, end: datetime): self.start = start self.end = end def construct(input_list: list[Event]) -> list[datetime]: # map生成二元组迭代器,chain.from_iterable负责展开所有元组 return list(chain.from_iterable(map(lambda x: (x.start, x.end), input_list))) # 测试示例 event_a = Event(start=datetime(2024,6,14), end=datetime(2024,6,15)) event_b = Event(start=datetime(2024,7,14), end=datetime(2024,7,15)) input_list = [event_a, event_b] output_list = construct(input_list) print(output_list) # 输出:[datetime.datetime(2024, 6, 14, 0, 0), datetime.datetime(2024, 6, 15, 0, 0), datetime.datetime(2024, 7, 14, 0, 0), datetime.datetime(2024, 7, 15, 0, 0)]
方法2:用嵌套生成器表达式配合map
如果不想引入itertools,可以用生成器表达式手动展开map返回的元组:
from datetime import datetime class Event: def __init__(self, start: datetime, end: datetime): self.start = start self.end = end def construct(input_list: list[Event]) -> list[datetime]: return list(item for pair in map(lambda x: (x.start, x.end), input_list) for item in pair)
关键说明
map的核心逻辑是一对一映射:每个输入元素对应一个输出元素。这里每个Event被映射成一个二元组,所以map返回的是二元组的迭代器。要得到扁平化列表,必须额外处理每个二元组,把里面的元素逐一取出,这就是chain.from_iterable或嵌套生成器的作用。
内容的提问来源于stack exchange,提问作者Sunfyr
相关产品推荐
相关产品推荐

