如何创建可索引的map()或修饰的list()?

时间:2018-07-24 21:35:27

标签: python python-3.x

我有一长串文件路径,例如:

images = ['path/to/1.png', 'path/to/2.png']

我知道我可以将此列表包装在一个映射迭代器中,该迭代器提供对通过函数映射的列表中项目的顺序访问:

image_map = map(cv2.imread, images)

然后,当我遍历列表时,我可以延迟加载那些图像文件:

next(image_map)
=> pixels

但是我想随机访问通过我的map函数映射的原始列表:

image_map[400]
=> pixels

我不想将其转换为list,因为那样会将我的所有图像加载到内存中,并且它们不适合内存:

# Bad:
list(image_map)[400]

对此进行思考的另一种方法可能是在list.__getitem__上使用装饰器。

我知道我可以对列表进行子分类,但是我真的希望有一种更简洁的方法。

2 个答案:

答案 0 :(得分:3)

为什么不创建访问器类?

class ImageList(object):
    def __init__(self, images):
        self.images = images

    def get_image(self, image_num):
        return cv2.imread(self.images[image_num])

您当然也可以缓冲读取的图像。

您还可以提供一种__getitem__方法来具有类似列表的访问权限:

def __getitem__(self, key):
    return cv2.imread(self.images[key])

用法:

images = ['path/to/1.png', 'path/to/2.png']

image_list = ImageList(images)

image = image_list.get_image(400)    # the same as 
image = image_list[400]              # this

顺便说一句:当然,您可以继承list的子类,但是在Python社区中,更显式的方法受到青睐。而且,这里有一个单独的类而不是子类list,这显然更加清楚。过度使用继承也不是最好的样式。

答案 1 :(得分:3)

如果无法将结果转换为map,则使用list的一个问题是只能迭代一次。如果您无法一次将整个内容放入内存中,并且需要随机访问,那么您将希望保留尽可能少的信息,直到您真正需要它为止-听起来像__getitem__叫做。因此,如果您打算编写image_map[n]以获取像素数据(而不是仅调用cv2.imread(image_map[n]),则必须创建一个列表子类,其__getitem__调用{{ 1}}。

例如

cv2.imread