Pythonic方式迭代序列,一次4项

bla*_*ted 31 python iteration

可能重复:
以块的形式迭代列表的最"pythonic"方法是什么?

我正在阅读一些PNG数据,每个像素有4个通道.我想一次迭代数据1个像素(意味着每4个元素= 1个像素,rgba).

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
Run Code Online (Sandbox Code Playgroud)

这种方式看起来并不"正确".是否有更多的Pythonic方法迭代序列,一次4个项目,并将这4个项目解压缩?

ken*_*ytm 33

(Python的itertools应该将所有食谱作为标准函数......)

你可以使用这个grouper功能:

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)
Run Code Online (Sandbox Code Playgroud)

然后你可以迭代像素

for r,g,b,a in grouper(4, raw_png_data):
  ....
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用

irpd = iter(raw_png_data)
for r,g,b,a in zip(irpd, irpd, irpd, irpd):  # use itertools.izip in Python 2.x
  ....
Run Code Online (Sandbox Code Playgroud)

请注意,如果迭代的长度不是4的倍数,这将切断最后几个字节.grouper函数使用OTOH izip_longest,因此额外的字节将填充为None.


Tom*_*cki 25

vars = [1, 2, 3, 4, 5, 6, 7, 8]
for a, b, c, d in zip(*[iter(vars)]*4):
    print a, b, c, d
Run Code Online (Sandbox Code Playgroud)


Joh*_*ooy 6

from itertools import izip
for r,g,b,a in izip(*[iter(data)]*4):
    ...
Run Code Online (Sandbox Code Playgroud)


exc*_*id3 -4

尝试这样的事情:

for red, green, blue, alpha in raw_png_data:
    #do something
Run Code Online (Sandbox Code Playgroud)

您可以提取多个项目,而无需使用迭代器。:)

编辑:这意味着 raw_png_data 需要是 4 个值元组的列表。将每个 rgba 组放入一个元组中,然后将其附加到 raw_png_data 并像我的示例一样进行迭代,这将是最 Pythonic 的。

  • 显然这不起作用,除非 raw_png_data 是元组列表。正确的? (7认同)
  • @excid3这就是这个问题所要求的,如何将原始序列分组为元组。 (3认同)