1 致谢
感谢网友“-柚子皮-”的帮助,
原文链接如下:
https://blog.csdn.net/pipisorry/article/details/45171451
感谢 Python Software Foundation的指导,
Python官方doc的链接如下:
https://docs.python.org/zh-cn/3/library/itertools.html#itertools.chain.from_iterable
2 前言
今天在阅读Detectron2的示例代码时,看到他们用了一个这样的语句做迭代器的链接:
# 上面是一些其他的标注信息的赋值代码……
annos = v["regions"]
objs = []
for _, anno in annos.items():
assert not anno["region_attributes"]
anno = anno["shape_attributes"]
px = anno["all_points_x"]
py = anno["all_points_y"]
poly = [(x + 0.5, y + 0.5) for x, y in zip(px, py)]
poly = list(itertools.chain.from_iterable(poly))
# 这里使用itertools.chain.from_iterable来将poly列表转换为一个chain迭代器
obj = {
"bbox": [np.min(px), np.min(py), np.max(px), np.max(py)],
"bbox_mode": BoxMode.XYXY_ABS,
"segmentation": [poly],
"category_id": 0,
"iscrowd": 0
}
objs.append(obj)
record["annotations"] = objs
dataset_dicts.append(record)
我感觉挺奇怪的,于是就查了一下,后来发现这是一种比较高效的连接多个迭代器的方法~
3 使用itertools.chain.from_iterable将多个迭代器进行高效的连接
3.1 itertools.chain.from_iterable的作用
itertools.chain.from_iterable可以用来连接多个迭代器,我们可以看看官方文档给出的介绍,
可以看到他可以连接两个迭代器'ABC'和'DEF'
其中输入参数iterables是多个迭代器的list类型,
3.2 将多个迭代器进行高效的连接
官方文档在sum(iterable, /, start=0)的描述中也建议到:
To concatenate a series of iterables, consider using
itertools.chain()
.
其实这样做的原因我们在3.1中就看到,也就是“从一个单独的可迭代参数中得到链式输入,该参数是延迟计算的。”,说明这里使用的是懒汉式的读取模式,所以在一定程度上可以提高读取数据的效率,因为不用一开始就获得整个的list,这也是iterable类型的优势之一;
3.3 备注
使用itertools.chain.from_iterable会使代码变得清晰易懂
感觉使用itertools.chain.from_iterable的可读性比使用sum(iterable, /, start=0)的可读性要高一些;