使用Pythonic方式每次迭代4个元素
可能重复的问题:
在处理列表时,最“Pythonic”的方式是什么?
我正在读取一些PNG格式的数据,每个像素有4个通道。我想要逐个像素地遍历这些数据(也就是说,每4个元素代表1个像素,分别是红色、绿色、蓝色和透明度)。
red_channel = 0
while red_channel < len(raw_png_data):
green_channel, blue_channel, alpha_channel = red_channel +1, red_channel +2, red_channel +3
# do something with my 4 channels of pixel data ... raw_png_data[red_channel] etc
red_channel += 4
这种方法似乎不是很“正确”。有没有更符合Python风格的方法,可以每次处理4个项目,并且将这4个项目拆分开来?
5 个回答
9
from itertools import izip
for r,g,b,a in izip(*[iter(data)]*4):
...
当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。
36
vars = [1, 2, 3, 4, 5, 6, 7, 8]
for a, b, c, d in zip(*[iter(vars)]*4):
print a, b, c, d
当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。
42
(Python的itertools库其实应该把所有的配方都做成标准函数……)
你可以使用 grouper
函数:
from itertools import zip_longest
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
然后你可以通过以下方式遍历像素:
for r,g,b,a in grouper(4, raw_png_data):
....
另外,你也可以使用:
irpd = iter(raw_png_data)
for r,g,b,a in zip(irpd, irpd, irpd, irpd): # use itertools.izip in Python 2.x
....
需要注意的是,如果你要处理的内容长度不是4的倍数,这样做会把最后几个字节切掉。另一方面,grouper
函数使用了 izip_longest
,所以多出来的字节会用None来填充。