Pythonic way to iterate over sequence, 4 items at a time
本问题已经有最佳答案,请猛点这里访问。
Possible Duplicate:
What is the most “pythonic” way to iterate over a list in chunks?
我正在阅读一些PNG数据,每个像素有4个通道。我想一次迭代1个像素的数据(意味着每4个元素=1个像素,rgba)。
1 2 3 4 5 | 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个项目解包?
(python的itertools真的应该使所有的食谱都成为标准函数…)
您可以使用
1 2 3 4 5 | from itertools import izip_longest def grouper(n, iterable, fillvalue=None): "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return izip_longest(fillvalue=fillvalue, *args) |
然后你可以迭代像素
1 2 | for r,g,b,a in grouper(4, raw_png_data): .... |
或者,您可以使用
1 2 3 | irpd = iter(raw_png_data) for r,g,b,a in zip(irpd, irpd, irpd, irpd): # use itertools.izip in Python 2.x .... |
请注意,如果iterable的长度不是4的倍数,那么这将切掉最后几个字节。Otoh,
1 2 3 | vars = [1, 2, 3, 4, 5, 6, 7, 8] for a, b, c, d in zip(*[iter(vars)]*4): print a, b, c, d |
1 2 3 | from itertools import izip for r,g,b,a in izip(*[iter(data)]*4): ... |
1 2 | for r, g, b, t in (data[i:i+4] for i in xrange(0, len(data)/4*4, 4)): print r, g, b, t |
尝试如下操作:
1 2 | for red, green, blue, alpha in raw_png_data: #do something |
您可以提取多个项,而不必使用迭代器。:)
编辑:这意味着原始数据需要是4个值元组的列表。将每个rgba组放入一个元组,然后将其附加到原始的png u数据中,并像我的示例一样进行迭代,这将是最简单的方法。