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

发布于 2024-09-13 00:45:39 字数 651 浏览 2 评论 0原文

可能的重复:
什么是最“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

这种方式看起来并不“正确”。有没有一种更 Pythonic 的方法来迭代一个序列,一次 4 个项目,并将这 4 个项目解压?

Possible Duplicate:
What is the most “pythonic” way to iterate over a list in chunks?

I am reading in some PNG data, which has 4 channels per pixel. I would like to iterate over the data 1 pixel at a time (meaning every 4 elements = 1 pixel, 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

This way doesnt really seem "right". Is there a more Pythonic way to iterate over a sequence, 4 items at a time, and have those 4 items unpacked?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱殇璃 2024-09-20 00:45:39

(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 的倍数,这将截断最后几个字节。OTOH,< code>grouper 函数使用 izip_longest,因此额外的字节将用 None 填充。

(Python's itertools should really make all recipes as standard functions...)

You could use the grouper function:

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)

Then you can iterate the pixels by

for r,g,b,a in grouper(4, raw_png_data):
  ....

Alternatively, you could use

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

Note that this will chop the last few bytes if the iterable's length is not a multiple of 4. OTOH, the grouper function uses izip_longest, so the extra bytes will be padded with None for that.

做个ˇ局外人 2024-09-20 00:45:39
vars = [1, 2, 3, 4, 5, 6, 7, 8]
for a, b, c, d in zip(*[iter(vars)]*4):
    print a, b, c, d
vars = [1, 2, 3, 4, 5, 6, 7, 8]
for a, b, c, d in zip(*[iter(vars)]*4):
    print a, b, c, d
沉溺在你眼里的海 2024-09-20 00:45:39
from itertools import izip
for r,g,b,a in izip(*[iter(data)]*4):
    ...
from itertools import izip
for r,g,b,a in izip(*[iter(data)]*4):
    ...
泡沫很甜 2024-09-20 00:45:39
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
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
大姐,你呐 2024-09-20 00:45:39

尝试这样的事情:

for red, green, blue, alpha in raw_png_data:
    #do something

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

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

Try something like this:

for red, green, blue, alpha in raw_png_data:
    #do something

You can pull out multiple items and never have to use an iterator. :)

Edit: This would mean that raw_png_data needs to be a list of 4 value tuples. It would be most pythonic to put each rgba group into a tuple and then append it to raw_png_data and iterate through like my example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文