Pythonic方式迭代序列,一次4个项目[重复]

Posted

技术标签:

【中文标题】Pythonic方式迭代序列,一次4个项目[重复]【英文标题】:Pythonic way to iterate over sequence, 4 items at a time [duplicate] 【发布时间】:2011-03-25 19:27:55 【问题描述】:

可能重复:What is the most “pythonic” way to iterate over a list in chunks?

我正在读取一些 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 个项目解包?

【问题讨论】:

【参考方案1】:

(Python 的 itertools 确实应该将 all recipes 设为标准函数...)

你可以使用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,grouper 函数使用izip_longest,因此额外的字节将用 None 填充。

【讨论】:

【参考方案2】:
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 列表长度等分到 4,迭代 4 这对我有用,但正如@EugeneNagorny 所说,任何使用它的人都应该注意,如果您的列表中的项目少于“等分”的倍数,它将省略“余数”。例如,对于列表中的 10 个值和 4 个等分试样,它只会发出两组四个值,忽略最后两个。【参考方案3】:
from itertools import izip
for r,g,b,a in izip(*[iter(data)]*4):
    ...

【讨论】:

【参考方案4】:
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

【讨论】:

并非所有序列都支持索引。 data 很可能是一个生成器。【参考方案5】:

试试这样的:

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

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

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

【讨论】:

显然这不起作用,除非 raw_png_data 是一个元组列表。对吗? 是的,但最好在创建 raw_png_data 时将它们分组为元组,因为每组 4 个值都是相关的。 @excid3 这就是这个问题要问的,如何将原始序列分组为元组。

以上是关于Pythonic方式迭代序列,一次4个项目[重复]的主要内容,如果未能解决你的问题,请参考以下文章

检测循环最终迭代的Pythonic方法[重复]

在满足条件之前不断迭代列表的最 Pythonic 方式?

几点技巧让你的 python 代码更加 pythonic

使用迭代器的最快(最 Pythonic)方式

迭代器

迭代器