代码之家  ›  专栏  ›  技术社区  ›  colllin spam_eggs

如何创建可索引映射()或修饰列表()?

  •  6
  • colllin spam_eggs  · 技术社区  · 6 年前

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

    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 回复  |  直到 6 年前
        1
  •  3
  •   Juergen    6 年前

    为什么不创建一个访问器类呢?

    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社区中,更倾向于使用explicite。这里更清楚的是要有一个单独的类而不是子类 列表 . 它也不是过度使用继承的最佳样式。

        2
  •  3
  •   MoxieBall    6 年前

    使用的一个问题 map 如果无法将结果转换为 list 你只能遍历一次。如果你不能一次将所有的信息放入内存,并且你需要随机访问,那么你需要尽可能少地保存信息,直到你真正需要它为止——这听起来像是 __getitem__ 被称为。因此,如果你想写 image_map[n] 获取像素数据(而不是仅仅调用 cv2.imread(image_map[n]) ,则必须创建一个列表子类 __获取项目__ 电话 cv2.imread .

    例如

    class cv2_list(list):
        def __getitem__(self, item):
            return cv2.imread(super().__getitem__(item))