首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python中的内存高效和干净的set()

python中的内存高效和干净的set()
EN

Code Review用户
提问于 2021-04-03 01:33:43
回答 2查看 123关注 0票数 -2

我试图在图像中获取唯一颜色的列表(rgba值)。以下是我的尝试:

代码语言:javascript
复制
# 1 - too ugly and clunky
all_colors = []
for i in range(width):
        for j in range(height):
                color = pix[i, j]
                if color not in all_colors:
                        all_colors.append(color)

代码语言:javascript
复制
# 2 - not memory-efficient, as it adds the whole list into memory
all_colors = list(set([pix[i, j] for i in range(width) for j in range(height)]))

编辑:这是设置:

代码语言:javascript
复制
from PIL import Image

img = Image.open("../Camouflage.png")
pix = img.load()

非常感谢。

EN

回答 2

Code Review用户

回答已采纳

发布于 2021-04-04 08:29:19

简单点怎么样?

代码语言:javascript
复制
all_colors = set(img.getdata())

或者让枕头做艰苦的工作:

代码语言:javascript
复制
all_colors = [color for _, color in img.getcolors()]

基准测试结果以及我的测试映像上的集合理解解决方案(因为您没有提供任何):

代码语言:javascript
复制
113 ms  set_comp
 68 ms  set_getdata
  1 ms  getcolors

115 ms  set_comp
 65 ms  set_getdata
  1 ms  getcolors

106 ms  set_comp
 62 ms  set_getdata
  1 ms  getcolors

使用img.getdata(),您可以得到一个“类似序列的对象”,它看起来很轻:

代码语言:javascript
复制
>>> img.getdata()
<ImagingCore object at 0x7f0ebd0f1e50>

>>> import sys
>>> sys.getsizeof(img.getdata())
32

基准代码:

代码语言:javascript
复制
from timeit import repeat
from PIL import Image

def set_comp(img):
    pix = img.load()
    width, height = img.size
    return {pix[i,j] for i in range(width) for j in range(height)}

def set_getdata(img):
    return set(img.getdata())

def getcolors(img):
    return [color for _, color in img.getcolors()]

funcs = set_comp, set_getdata, getcolors

def main():
    img = Image.open("test.png")
    for _ in range(3):
        for func in funcs:
            t = min(repeat(lambda: func(img), number=1))
            print('%3d ms ' % (t * 1e3), func.__name__)
        print()

main()
票数 6
EN

Code Review用户

发布于 2021-04-03 01:45:36

没有必要将list传递给set()。使用生成器表达式:

代码语言:javascript
复制
all_colors = set(pix[i,j] for i in range(width) for j in range(height))

或者,使用一套理解:

代码语言:javascript
复制
all_colors = {pix[i,j] for i in range(width) for j in range(height)}

我通过构建一组1_000_000项来对它们进行计时。平均而言,集合理解速度小于10 On,且它们之间的距离在1 std之间。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/259036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档